【问题标题】:How to remove null values from nested arrays如何从嵌套数组中删除空值
【发布时间】:2019-04-25 11:32:30
【问题描述】:

此代码从数组中删除所有空值:

var array = [ 0, 1, null, 2, "", 3, undefined, 3,,,,,, 4,, 4,, 5,, 6,,,, ];

var filtered = array.filter(function (el) {
  return el != null;
});

console.log(filtered);

但是当我在具有空值的嵌套数组的数组上尝试此操作时,不会删除空值:

var array = [ [ 1, null, 2 ], [ 3, null, 4 ], [ 5, null, 6 ] ];

var filtered = array.filter(function (el) {
  return el != null;
});

console.log(filtered);

预期的输出是:

[ [ 1, 2 ], [ 3, 4 ], [ 5, 6 ] ]

而不是实际输出:

[ [ 1, null, 2 ], [ 3, null, 4 ], [ 5, null, 6 ] ]

如何更改我的示例以过滤嵌套数组中的空值?

【问题讨论】:

  • 为什么是索引 2?结果的内部数组的索引 1 会发生什么?嵌套数组的原因是什么?
  • 也许看stackoverflow.com/a/38132582/6523409。过滤器应该被递归调用。
  • @Nina Scholz,我有一个很长的数组,里面有成千上万的行,里面有空元素。我想让它适用于每个空元素,不仅适用于索引 1。
  • 我的意思是,你是如何从给定的数组中得出结果的?
  • 我已经编辑了您的问题,希望能为大家澄清。如果我与您的初衷偏离太远,请随时通过the revisions page回滚我的编辑

标签: javascript arrays


【解决方案1】:
var filterFn = function(item) {
    if (item instanceof Array) {
        // do this if you want to remove empty arrays:
        var items = item.splice(0).filter(filterFn);
        var length = items.length;
        Array.prototype.push.apply(item, items);
        return length;
        // if you want to keep empty arrays do this:
        var items = item.splice(0);
        Array.prototype.push.apply(item, items.filter(filterFn))
        return true;
    }
    return item != null;
};
array = array.filter(filterFn);

这也适用于超过 2 层,因为它是递归的。

【讨论】:

【解决方案2】:

如果你的array-of-arrays只有一层,那么你可以像这样map它:

var filtered = array.map(subarray => subarray.filter(el => el != null));
console.log(filtered);

【讨论】:

  • 干得好。这是唯一需要考虑的答案。这个问题太简单了,不能用 reduce 等过度设计。
【解决方案3】:
var arraylist = [0, 1, null, 5];
var i = arraylist.length;
var j =0;
var newlist = [];

while(j < i){

if(arraylist[j] != null){

    newlist.push(arraylist[j]);

}

j++;
}

console.log(newlist);

https://jsfiddle.net/L4nmtg75/

【讨论】:

    【解决方案4】:

    你需要递归过滤null,像这样:

    function removeNull(array) {
      return array
        .filter(item => item !== null)
        .map(item => Array.isArray(item) ? removeNull(item) : item);
    }
    

    此函数接受一个数组,并递归删除所有 null 实例。

    首先,我采用了您的解决方案并将其包装在一个函数中,以便能够调用它。

    然后,在过滤完项目之后,就像映射剩余的项目一样简单,检查每个项目是否是一个数组,然后对每个项目调用 removeNull 。

    编辑:我最初的代码中有错字,但现在应该可以了。

    【讨论】:

      【解决方案5】:

      您的示例删除了 undefined 值和 null 值,并且您的预期输出反映了这一点,所以我假设您的意思是要递归删除 undefinednull价值观。您的示例使用loose equality comparison,这意味着它将匹配nullundefined。虽然这有效,但最好通过使用=== 的严格相等比较来明确您正在检查的内容。

      你将需要使用递归:

      递归

      函数调用自身的行为。递归用于解决包含较小子问题的问题。

      -https://developer.mozilla.org/en-US/docs/Glossary/Recursion

      这也意味着您将要使用Array#reduce 而不是Array#filter。使用新数组作为累加器。

      然后对于输入数组中元素不为空或未定义的每个元素:

      • 如果元素是Array的实例,则将对该元素调用该函数的结果推送到累加器数组中,
      • 否则将元素推送到累加器数组中

      将reduce回调结束时的累加器数组作为累加器返回

      const input = [ [ 1, null, 2 ], null,,,,, [ 3, null, 4 ],,,,, [ 5, null, 6 ],,,,, [ 7, [ 8, undefined, 9 ], 10 ] ]
      
      function recursiveValues(input) {
        if(!(input instanceof Array)) return null
        return input.reduce((output, element) => { 
           if(element !== null && element !== undefined) {
              if(element instanceof Array) {
                  output.push(recursiveValues(element))
              } else {
                  output.push(element)
              }
          }
          return output
        }, [])
      }
      
      const output = recursiveValues(input)
      
      console.log(JSON.stringify(output))

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-08-29
        • 1970-01-01
        • 2019-09-05
        • 1970-01-01
        • 1970-01-01
        • 2021-11-30
        相关资源
        最近更新 更多