3

the only way I can think to do this is to do something like:

for current array length,
  for array to check length
   if current array i === array to check i
      true

Essentially I have the following:

arr = [[1,2], [0,3]];

When I want to add another array to this arrays: [1,2] I need to first see if it exists, if it does do not push it on to the array, if it doesn't then push it.

Is there some really simple, clean readable way to check if an array exists in an array of arrays before pushing it on to the list of elements?

Update:

it should be pretty simple, you have array:

arr = [[1,2], [0,3]];

You try and push:

[1,2]

Nothing happens.

You try and push: [4,6]. New array: [[1,2], [0,3], [4,6]];

TheWebs
  • 12,470
  • 30
  • 107
  • 211
  • I don't actually know how to implement this, so pseudo code is all I got ... – TheWebs Nov 05 '15 at 20:29
  • So at least show a couple of inputs, and matching outputs, that demonstrate your desired behavior. – Amit Nov 05 '15 at 20:30
  • You're not far off. You'd want to loop over the first array and then compare the inner arrays against your check. But you can't use a simple comparison operator for that. See [this](http://stackoverflow.com/a/14853974/1457603) for how to compare arrays. – Blake Hair Nov 05 '15 at 20:32
  • I thought there would be some simple lodash way or some underscore way of doing this ... ?? – TheWebs Nov 05 '15 at 20:33
  • Is that always the level of your complexity? a few numerical values inside the sub arrays? – Amit Nov 05 '15 at 20:33
  • yup thats as complicated as it gets – TheWebs Nov 05 '15 at 20:34
  • When you say your array contains `[1,2]` and then pushing `[1,2]` does nothing, are they the same object reference? Or you want to do nothing when pushing an array which contains the same items as an already pushed one? – Oriol Nov 05 '15 at 20:39
  • I would use Array's [`filter`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter) or [`find`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find) to check for presence. – hindmost Nov 05 '15 at 20:40
  • Pushing `[2,1]` would add it to the array right? – Pluto Nov 05 '15 at 20:50

3 Answers3

3

Since the complexity is limited, a simple solution exists:

function maybePush(to, val) {
  if(!to.some(function(curr) {
      return curr.length !== val.length ||
        curr.some(function(v, i) { return val[i] === v; });
    })) {
     to.push(val);
  }
}


arr = [[1,2], [0,3]];
maybePush(arr, [1,2]);
maybePush(arr, [5,6]);
console.log(arr);

You'd probably want to add some guards, check that what you expect to be an array really is an array and so on (left out for clarity)...

The idea is simple, check if any of the values of the outer array is equal to the val array, using an iterative comparison.

Amit
  • 45,440
  • 9
  • 78
  • 110
1

If you know your array arr contains only integers and arrays, a simple check to see if the array matches the flattened array will indicate if the array contains inner arrays.

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

if (JSON.stringify(arr) === JSON.stringify([].concat.apply([], arr))) {
  // Does not contain an array
}

The snippet [].concat.apply([], arr) flattens the array arr.

Brett DeWoody
  • 59,771
  • 29
  • 135
  • 184
  • `[].concat` creates a new, different array. `===` will always return false. – Oriol Nov 05 '15 at 20:40
  • You are correct @Oriol, I forgot to stringify the arrays. – Brett DeWoody Nov 05 '15 at 21:01
  • This doesn't do what the OP wants, and the approach doesn't work since it unconditionally concatenates the new array to the end of the existing array, creating a new, different array with more members therefore it will always evaluate to false. – RobG Nov 05 '15 at 21:08
0

Using underscore you can do this:

Initial approach:

    var i = _.findIndex(arr, function (e) {
         return (e.join(',') === arr_elem.join(','));
    });

    if (i === -1) {
        arr.push(arr_elem);
    }

EDIT Considering performance (Also read the comments here), it would be better to check array equality using a brute loop approach:

function arraysEqual(arr1, arr2) {
    if(arr1.length !== arr2.length)
        return false;
    for(var i = arr1.length; i--;) {
        if(arr1[i] !== arr2[i])
            return false;
    }

    return true;
}

var i = _.findIndex(arr, function (e) {
     return arraysEqual(arr_elem, e);
});

if (i === -1) {
    arr.push(arr_elem);
}
Community
  • 1
  • 1
Ananth
  • 4,227
  • 2
  • 20
  • 26