1

So I need to remove empty (undefined) items from the multidimensional array. Atm my code looks like this (it's a method I run so that's why i am using this:

f: function(arr) {
    var __ = this;
    arr = arr.filter(function(item) {
        return Array.isArray(item) ? __.f(item) : typeof(item) !== "undefined";
    });
return arr;
}

but if i run console.log(myObject.f([1, 2, , , , , 3, 4, [5, , , , , ], 6, , , , 8, 3, [[[], 9]]])); i get [ 1, 2, 3, 4, [ 5, , , , ], 6, 8, 3, [ [ [], 9 ] ] ] and that is kinda weird result. I goes pretty well for the first layer but removes only one undefined from inner layers. Also I would like to remove a subarray that consists of no items.

3 Answers 3

2

Use reductions people! They are beautiful!

function stripUndefined (arr) {
  return arr.reduce(function (result, item) {
    result.push( Array.isArray(item) && !item.length ? stripUndefined(item) : item );
    return result;
  }, []);
}
Sign up to request clarification or add additional context in comments.

6 Comments

Very elegant, thanks! So I take it reduce skips undefined items entirely and that's why it does not throw a syntax error regarding length check of undefined
Correct. Strictly speaking Gilad's answer is also a reduction - the process of accumulating some result while looping over a collection - but Array.prototype.reduce does happen to exclude "holes" in the array
Yes, I understand that, but here result is a collector that all the items of an array are reduced into, and item is the next iteration of an item queue of an original array. What grabbed my attention is the idea that reduce goes down the array to reduce it, item by item. But why does not ternary throw an error when it reaches undefined item as you can not check the length of undefined?
"reduce executes the callback function once for each element present in the array, excluding holes in the array"
I added that after noticing that undefined values are skipped but null is not. Also because strings have a length.
|
2

How about something like this:

var arr = [1, 2, , , , , 3, 4, [5, , , , , ], 6, , , , 8, 3, [[[], 9]]];

var remove = function (array) {
  var result = [];

  array.forEach(function (item) {
    if (Array.isArray(item) && item.length!=0) {
      // Item is a nested array, go one level deeper recursively
      result.push(remove(item));
    }
    else if (typeof item !== 'undefined') {
      result.push(item);
    }
  });

  return result;
};

And then console.log(remove(arr)); gives us [1, 2, 3, 4, [5], 6, 8, 3, [[[], 9]]]

2 Comments

Thanks a lot, simple but smart! Also I wonder, is there a technical possibility to cut out that null-length array [] (the deeper nested one)?
@AlexBykov See my answer below
0

Similar to Gilad's answer, but completely skipping arrays that result in an empty array (eg [,,,,,])

function cleanArray2d(array){
  var result = [];

  array.forEach(function (item) {
    if (Array.isArray(item) && item.length!=0) {
      // Item is a nested array, go one level deeper recursively

      var nestedArray = cleanArray2d(item);
      if (nestedArray.length > 0)
        result.push(cleanArray2d(item));
    }
    else if (typeof item !== 'undefined' && item != "") {
      result.push(item);
    }
  });

  return result;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.