【问题标题】:Javascript: How to clear undefined values from an arrayJavascript:如何从数组中清除未定义的值
【发布时间】:2012-03-24 15:57:20
【问题描述】:

我正在尝试遍历一个数组并删除并跳过元素,直到只有一个元素存在。我试过拼接,但它弄乱了我的循环,因为来自 arr[1] 的元素然后变成了 arr[0] 等等。

假设有 10 个人。我想删除第 1 个人,然后保留第 2 个人,然后删除第 3 个人并保留第 4 个人。这种模式将一直持续到只剩下一个人。

任何形式的帮助都可以。

【问题讨论】:

  • “直到只剩下一个”是什么意思?一次通过数组后,您会将其从 10 个元素(人)减少到 5 个元素(人)-您是说要继续重复该过程(重复通过)直到数组中只有一个元素吗?
  • 如果你只想要一个元素......那你为什么需要一个循环?
  • @MathWizz,这也是我的想法,剩余元素的位置可以不用循环计算出来。
  • 是的,我会重复这个过程,直到只剩下一个。

标签: javascript arrays undefined-index


【解决方案1】:
>If you are getting undefined during deletion of the key-pair, Then to prevent "undefined" you can try code given below to delete key-pair  


   1) test = ["1","2","3","4",""," "];
   2) var delete = JSON.stringify(test);   
      case1) delete = delete.replace(/\,""/g,'');  
         or  
      case2) delete = delete.replace(/\," "/g,'');  
         or  
      case3) delete = delete.replace(/\,null/g,'');  

   3) var result = JSON.parse(delete);  

【讨论】:

    【解决方案2】:

    当你拼接时,只需减少你的循环索引。

    有很多好的建议,我将发布不同选项的代码,您可以决定使用哪个

    拼接时递减索引 http://jsfiddle.net/mendesjuan/aFvVh/

    var undef;
    var arr = [1,2, undef, 3, 4, undef];
    for (var i=0; i < arr.length; i++) {
        if ( arr[i] === undef ) {
            arr.splice(i,1);
            i--;
        }
    }
    

    向后循环 http://jsfiddle.net/mendesjuan/aFvVh/1/

    var undef;
    var arr = [1,2, undef, 3, 4, undef];
    for (var i=arr.length - 1; i >=0; i--) {
        if ( arr[i] === undef ) {
            arr.splice(i,1);
        }
    }
    

    复制到新数组 http://jsfiddle.net/mendesjuan/aFvVh/2/

    var undef;
    var arr = [1,2, undef, 3, 4, undef];
    var temp = [];
    for (var i=0; i < arr.length; i++) {
        if ( arr[i] !== undef ) {
            temp.push(arr[i])
        }
    }
    arr = temp;
    

    使用过滤器,这只是创建新数组的一种奇特方式

    var undef;
    var arr = [1,2, undef, 3, 4, undef];
    arr = arr.filter(function(item){
        return item !== undef;
    });
    

    在所有这些示例的末尾,arr 将是 [1,2,3,4]

    性能

    IE 11、FF 和 Chrome 一致认为 Array.splice 是最快的。与Array.filter. 相比,速度是Array.filter. 的10 倍(Chrome),20 倍(IE 11) 与Array.slice 相比,将项目放入新数组也很慢。看 http://jsperf.com/clean-undefined-values-from-array2

    看到 IE 在这方面领先,并且看到 Chrome 落后于 FF 和 IE,我真的很惊讶。我想我从来没有用这个结果进行过测试。

    【讨论】:

      【解决方案3】:

      过滤虚假项目:

      var a=[1,2,"b",0,{},"",NaN,3,undefined,null,5];
      var b=a.filter(Boolean); // [1,2,"b",{},3,5]
      

      【讨论】:

      • @alexoviedo999 迄今为止我见过的最好的一个。我通常检查 undefineds 或 true
      • alexoviedo999 哇!谢谢!
      【解决方案4】:

      如果您有任何机会使用CoffeeScript,那么要从 Array 中删除 undefined,请执行此操作

      values = ['one', undefined]
      values = (item for item in values when item != undefined) 
      
      values
      /* => ['one'] */
      

      【讨论】:

        【解决方案5】:
          while(yourarray.length>1) //only one left
            {
            // your code
            }
        

        【讨论】:

        • length 是数组的属性,而不是函数。
        【解决方案6】:
        function removeUndefined(array)
        {
            var i = 0;
            while (i < array.length)
                if (typeof array[i] === 'undefined')
                    array.splice(i, i);
                else
                    i++;
            return array;
        }
        

        编辑:我是根据标题写的。看起来这个问题提出了完全不同的问题。

        【讨论】:

        • 如果 array[i] 为空或 false 或 0,它也会被删除。
        • 我想你的意思是.splice(i, 1)
        • @shenhengbin 我已经解决了。
        【解决方案7】:

        令人惊讶的是,没有人回答最好和正确的方法:

        1. 创建新数组
        2. 迭代旧数组,只将要保留的元素推送到新数组中

        一些功劳归于@nnnnnn comment

        【讨论】:

        【解决方案8】:

        这可能不是你想要的,但你可以很容易地计算出这个过程结束时的最终元素,然后抓住它。假设数组的元素是连续的,并且从 arr[0] 开始,可以发现:

        var logBase2OfLength = Math.floor(Math.log(arr.length) / Math.log(2));
        var finalElement = arr[(1 << logBase2OfLength) - 1];
        

        基本上,如果您取小于或等于数组中元素数量的 2 的整数幂,那么这就是在所有循环和删除之后将保留的元素的位置。

        【讨论】:

          【解决方案9】:

          这是给你的样本

          <script lanauge = "javascript">
              var arr = ["1","2","3","4"];
              delete arr[1];// arr[1] is undefined
              delete arr[2];// arr[2] is undefined
          
              // now arr.length is 4
          
              var todelete = [];
              for (i = 0 ; i < arr.length ;i++)
              {
                  if (typeof arr[i] == 'undefined') todelete.push(i);
              }
          
              todelete.sort(function(a, b) { return b-a }); // make the indeies from big to small
          
              for (i = 0;i < todelete.length; i ++)
              {
                  arr.splice(todelete[i],1);
              }
          
              // now arr.length is 2
          
          </script>
          

          【讨论】:

          • .sort() 方法并没有按照评论所说的那样做。如果没有回调函数,它将执行升序字典排序。
          【解决方案10】:

          最好的办法是创建数组的副本,然后从原始数组拼接。

          或者只是去使用一个集合(键->值)并删除键,例如

           People = {a: "Person A", b: "Person B", c:"Person C"};
           delete People.a;
           delete People.c;  //now the People collection only has 1 entry.
          

          您可以将 a,b,c 替换为仅以数字为例,

           People = {0: "Person A", 1: "Person B", 2:"Person C"};
           delete People[0];
           delete People[1];
          

          【讨论】:

          • 你没抓住重点,OP知道要拼接,问题是删除一个项目后索引已经过时了
          • @Juan Mendes,最好使用 key->value 集合代替
          【解决方案11】:

          没有准确收集您想要实现的目标,但我觉得您依赖数组中某个项目的位置索引来继续您的程序。在这种情况下,我建议使用散列数组,即 KeyValue 对数组。

          在这种情况下,arr["2"] 始终指向您最初放入其中的项目。因此,您可以在逻辑/数字上循环遍历,而不必担心位置的变化。

          小心类型转换的风险和陷阱!

          【讨论】:

            【解决方案12】:

            循环向后。 (因此删除项目不会影响尚未处理的元素的索引。)

            【讨论】:

              【解决方案13】:

              您不应该在迭代过程中更改集合,不仅仅是 JavaScript,而是所有语言,定义一个新数组并在其中添加您要删除的数组,然后再迭代该数组以从第一个数组中删除。

              【讨论】:

              • 你可以改变它,如果你控制索引。但是,这比我的建议更不容易出错
              • 如何将您想要保留的那些添加到第二个数组中,然后最后用第二个替换第一个数组?省去了第二次迭代。
              • 我的意见是我们应该尽量保持我们的代码简单易读,我的权宜之计只是告诉我,写一个奇怪的复杂循环只会带来错误和混淆别人
              • 我误读了西蒙的建议,真正简单的方法是 nnnnnn 建议的(在此答案下),将其复制到新数组
              • 我最终使用了 3 个数组,首先是作为循环基础的原始数组。在循环中使用了 2 个数组。第二个数组包含那些在该迭代中被跳过的数组,另一个是一个空数组。在每次迭代结束时,我都会这样做。 arr1 = arr2; arr2 = arr3; 我不确定这是否是最好的解决方案,但它是有意义的,就像西蒙所说的那样,让它变得更简单并且有效。
              猜你喜欢
              • 2015-04-20
              • 2020-09-14
              • 1970-01-01
              • 1970-01-01
              • 2019-07-14
              • 1970-01-01
              • 2014-02-23
              • 1970-01-01
              相关资源
              最近更新 更多