简体   繁体   English

使用splice从数组中删除空值

[英]remove null values from arrays with splice

I'm trying to make a function to remove null values from multidimensional arrays, but it doesn't work very well. 我正在尝试创建一个从多维数组中删除空值的函数,但它不能很好地工作。 It does not penetrate to the last layer of arrays, and does not remove when two null values are adjacent. 它不会穿透到最后一层数组,并且在两个空值相邻时不会删除。

function isArray(obj) {
    // http://stackoverflow.com/a/1058753/1252748
    return Object.prototype.toString.call(obj) === '[object Array]';
}

function removeEmptyArrayElements(obj) {

    for (key in obj) {
        if (obj[key] === null) {

            obj = obj.splice(key, 1);

        }
        var isArr = isArray(obj[key]);
        if (isArr) {
            removeEmptyArrayElements(obj[key]);
        }

    }
    return obj;
}

Don't remove elements from an object while you are iterating over it. 迭代时,不要从对象中删除元素。

Don't use for ... in on Arrays. 不要在数组中使用for ... in

Do take advantage of higher-order functions like filter and map . 利用filtermap等高阶函数。 Try this: 尝试这个:

function removeEmptyArrayElements(arr) { 
   if (!isArray(arr)) {
      return arr;
   } else {
       return arr.filter( function(elem) { 
          return elem !== null
       } ).map(removeEmptyArrayElements)
   }
}

Explanation: 说明:

"Higher-order" functions are functions that use other functions as values - either accepting them as parameters, or returning them, or both. “高阶”函数是使用其他函数作为值的函数 - 将它们作为参数接受,或者将它们作为参数,或者两者都返回。 In this case I used two methods of Javascript's Array class which accept a function as a parameter and use it to build and return a new array. 在这种情况下,我使用了两种Javascript的Array类方法,它接受一个函数作为参数,并使用它来构建和返回一个新数组。

someArray.filter( function ) calls function on every element of someArray and returns a new array containing only the elements for which function returned true. someArray.filter( function )someArray每个元素上调用函数 ,并返回一个新数组,该数组仅包含函数返回true的元素。 The function I passed in this case is function(elem) { return elem !== null } - that is, an anonymous function that returns true if the element is not null. 我在这种情况下传递的函数是function(elem) { return elem !== null } - 也就是说,如果元素不为null,则返回true的匿名函数。 So the result of that filter call is the original array with all the nulls removed. 因此,该filter调用的结果是删除了所有空值的原始数组。

Now we want to remove any nulls from any elements of the result that are themselves arrays. 现在我们要从结果的任何元素中删除任何空值,这些元素本身就是数组。 I used map for that. 我使用map someArray.map( function ) also calls function on every element of the array, but instead of returning a subset of its input based on those results, it just returns the results themselves. someArray.map( function )也在数组的每个元素上调用函数 ,但不是根据这些结果返回其输入的子集,而是仅返回结果本身。 For example, [1,2,3].map(function(x){return x*2}) returns the array [2,4,6] . 例如, [1,2,3].map(function(x){return x*2})返回数组[2,4,6] In this case, the function we pass is the one we're in the middle of defining .. a recursive call back to removeEmptyElements . 在这种情况下,我们传递的函数是我们正在定义的函数..递归回调给removeEmptyElements

We do need a way to stop this endless cycle of calling ourselves, and that's what the outer if is for - when called on an element that isn't an array, we just return it as-is. 我们确实需要一种方法来阻止这种无限循环的自我调用,这就是外部if的用途 - 当在一个不是数组的元素上调用时,我们只是按原样返回它。

You're looping over an array you are deleting from. 您正在循环删除要删除的数组。 This gives you the "does not remove when two null values are adjacent" bug. 这给你“当两个空值相邻时不删除”的 bug。 The "It does not penetrate to the last layer of arrays" part is probably because you're not reassigning the value at obj[key] . “它不会渗透到最后一层数组”部分可能是因为你没有在obj[key]重新分配值。 Arrays are copied by value, not referenced. 数组按值复制,未引用。

I'd do it like this: 我这样做:

function isArray(obj) {
    // http://stackoverflow.com/a/1058753/1252748
    return Object.prototype.toString.call(obj) === '[object Array]';
}

function removeEmptyArrayElements(arr) {
    var i;
    for (i = 0; i < arr.length; i += 1) {
        if (arr[i] === null) {
            arr = arr.splice(i, 1);
            i -= 1; // decrement counter!

        } else if (isArray(arr[i])) {
            arr[i] = removeEmptyArrayElements(arr[i]);
        }
    }
    return arr;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM