【问题标题】:how to remove null, undefined, NaN, 0s, falses and empty string from an array in JavaScript?如何从 JavaScript 中的数组中删除 null、undefined、NaN、0、false 和空字符串?
【发布时间】:2016-07-04 17:15:38
【问题描述】:

我编写了一个脚本来使用 .splice() 删除任何 null、未定义、0、false 或空字符串值,但代码只删除了 NaN 和 0。

这是我尝试过的:

function remove(arr){ // input [NaN, 0, 15, false, -22, '',undefined, 47, null]
    var bin = [];
    for (var i =0; i<arr.length; i++){
        if (arr[i] == (NaN || 0 || false || "" || undefined || null)){
            arr.splice(arr[i],1);
        }
    }
  console.log(arr); // Expected output [15, -22, 47]
}

【问题讨论】:

  • arr = arr.filter(e =&gt; e);
  • arr = arr.filter(Boolean) 是 ES5 内置的。
  • 您在哪里找到语法x == (a || b || c || d),您希望它做什么?为什么要尝试使用splice 而不是使用filter 来创建新数组?
  • 我试图检查 x 是否等于 a 或 b 或 c 或 d,我可以从你的评论中看出这是错误的语法,你能解释一下原因吗?我使用 splice 因为我是编程新手,所以我不知道更好

标签: javascript arrays


【解决方案1】:

代码问题:

  1. 从最后一个元素到第一个元素遍历数组
  2. Array#splice 期望第一个参数作为索引,而不是项目本身
  3. 要检查元素是否为NaN,请使用isNaN()
  4. 要与多个值进行比较,请将元素分别与每个项目进行比较

工作代码:

function remove(arr) {
    for (var i = arr.length - 1; i >= 0; i--) {
        if (isNaN(arr[i]) || arr[i] === 0 || arr[i] === false || arr[i] === "" || arr[i] === undefined || arr[i] === null) {

        // Which is same as
        // if (!arr[i]) {
            arr.splice(i, 1);
        }
    }

    console.log(arr); // Expected output [15, -22, 47]
}

remove([NaN, 0, 15, false, -22, '', undefined, 47, null]);

使用Array#filter

arr = arr.filter(e => e);

var input = [NaN, 0, 15, false, -22, '',undefined, 47, null];

var filteredArr = input.filter(e => e);
document.body.innerHTML = '<pre>' + JSON.stringify(filteredArr, 0, 4) + '</pre>';

或者正如@dandaviscomment 中所说的那样

arr = arr.filter(Boolean);

var input = [NaN, 0, 15, false, -22, '',undefined, 47, null];

var filteredArr = input.filter(Boolean);
document.body.innerHTML = '<pre>' + JSON.stringify(filteredArr, 0, 4) + '</pre>';

【讨论】:

  • 仔细看,似乎确实需要突变,所以 splice() 可能仍然需要。
  • @dandavis 没看懂你的最后一句,但使用splice添加了代码
  • @Tushar 非常感谢您的回答,我尝试运行您的代码,但仅将迭代更改为从第一个元素计数到最后一个元素,但它不起作用,而您的原始方法有效,会请解释一下为什么升序循环不起作用?
  • @MohamedHegazy 升序将不起作用,因为当使用 splice 时,数组将被更新,并且下一个元素上的 index 将不起作用。请参阅this fiddle,在控制台中缺少一些元素(0-22)。
  • @dandavis Mutation 并不是真正需要的,我只是在解决这个练习,所以我认为 splice 可以完成这项工作
【解决方案2】:

这个解决方案可能效率不高

function filterArray(el) {
    return (typeof (el) === "number" && el != 0 && !isNaN(el));
}

arr = [NaN, 0, 15, false, -22, '', undefined, 47, null];
console.log(arr.filter(filterArray));

jsfiddle

【讨论】:

  • 这不会删除字符串吗?
  • 使用真实性怎么样? console.log(arr.filter(function(n){return n;}))
【解决方案3】:

使用lodash

console.log(_.compact(arr));

【讨论】:

    【解决方案4】:

    您指的是使用splice,所以我假设您想要一个就地(变异)解决方案。这是一个简单快捷的方法:

    function compact(a) {
      var i = 0, j = 0;
    
      while (i < a.length) {
        var v = a[i++];
        if (v) a[j++] = v;
      }
    
      a.length = j;
    }
    

    如果您关心(而且您可能不关心),这比在splice 上的循环快 10 倍。见http://jsperf.com/compacting-an-array

    如果您想要一个创建新数组的解决方案,使用filter 在其他答案中给出的替代方案很好,但这是一个基本版本:

    function compact(a) {
      var i = 0, j = 0, result = [];
    
      while (i < a.length) {
        var v = a[i++];
        if (v) result[j++] = v;
      }
    
      return result;
    }
    

    【讨论】:

    • 变异意味着你改变了输入。这就是splice 所做的,这就是我的第一个示例代码的工作方式。突变(就地)的替代方法是创建一个仅包含您想要的值的新数组。这就是filter 的工作原理,也是我的第二个示例代码的工作原理。
    【解决方案5】:
     function bouncer(arr) {
      var newArr=arr.slice(0);
      var n=0;
      for(var i=0; i<arr.length;i++){
        if(arr[i]==false||arr[i]==null||arr[i]==0||arr[i]==""||arr[i]==undefined||Number.isNaN(arr[i])==true){
          newArr.splice(n,1);
    
        } else n++;
      }
      console.log(newArr);
      return newArr;
    }
    
    bouncer([null, NaN, 1, 2, undefined,0,'a']);
    

    我曾尝试使用 slice()... 输入为 [null, NaN, 1, 2, undefined,0,'a'] 并按预期返回 [ 1, 2, 'a'] ... 希望对您有所帮助

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-04-15
      • 1970-01-01
      • 2012-12-17
      • 1970-01-01
      • 2016-05-30
      • 1970-01-01
      • 2015-11-02
      • 1970-01-01
      相关资源
      最近更新 更多