0

I have the following code that doesn't work with nested arrays (it works with simple arrays, though):

var array1 = [["501", 1800, "floorsRegion1", 0], ["502", 1800, "floorsRegion1", 0], ["503", 1800, "floorsRegion1", 0]];
var array2 = [["501", 1800, "floorsRegion1", 0]];

var duplicatesArray = array1.filter(function(val) {
  return array2.indexOf(val) !== -1;
});
console.log(duplicatesArray); // should return [["501", 1800, "floorsRegion1", 0]]; but it doesn't currently

If instead of nested arrays, I had simple numbers or strings, it would work and 'duplicatesArray' would contain the dupes. But JS doesn't compare the whole arrays as values, so my code doesn't work.

Only the val[0] is essential to compare in those nested arrays, but result array must contain the whole nested arrays for duplicates.

I found several similar solutions, but they remove the dupes instead of returning an array with those dupes.

Maria Blair
  • 309
  • 1
  • 3
  • 9
  • 4
    Possible duplicate of [How to compare arrays in JavaScript?](https://stackoverflow.com/questions/7837456/how-to-compare-arrays-in-javascript) – jhpratt Jan 04 '19 at 00:33
  • No, it's not the same because I use a different way to filter through the master array, and the end result should contain only duplicates, not remove them. – Maria Blair Jan 07 '19 at 18:10
  • All you're looking for is how to compare arrays. Whether you're preserving or removing is irrelevant. – jhpratt Jan 07 '19 at 19:36

1 Answers1

3

If you only care about the item at index 0, then you can filter using some and check id some item in array2 it's first value equals the first value of the current item being filters:

var array1 = [["501", 1800, "floorsRegion1", 0], ["502", 1800, "floorsRegion1", 0], ["503", 1800, "floorsRegion1", 0]];
var array2 = [["501", 1800, "floorsRegion1", 0]];

let filtered = array1.filter(arr => array2.some(arr2 => arr2[0] == arr[0]))
console.log(filtered)


// with two items in array2:

array1 = [["501", 1800, "floorsRegion1", 0], ["502", 1800, "floorsRegion1", 0], ["503", 1800, "floorsRegion1", 0]];
array2 = [["501", 1800, "floorsRegion1", 0], ["503", 1800, "floorsRegion1", 0]];

filtered = array1.filter(arr => array2.some(arr2 => arr2[0] == arr[0]))
console.log(filtered)

This isn't very efficient because it looks thought array2 for every item in array1. If the arrays were large it would be worth making a lookup with an object or Set that allows quicker lookups. Something like:

var array1 = [["501", 1800, "floorsRegion1", 0], ["502", 1800, "floorsRegion1", 0], ["503", 1800, "floorsRegion1", 0]];
var array2 = [["501", 1800, "floorsRegion1", 0], ["503", 1800, "floorsRegion1", 0]];

let known = new Set(array2.map(item => item[0]))

let filtered = array1.filter(arr => known.has(arr[0]))
console.log(filtered)
Mark
  • 90,562
  • 7
  • 108
  • 148
  • Mark, your solution does the opposite of what I need. Your 'filtered' returns the unique nested arrays, and I need to return the duplicate arrays. The result should be [["501", 1800, "floorsRegion1", 0]] which is an arrays that appears in both array1 and array2. – Maria Blair Jan 04 '19 at 00:50
  • 1
    Sorry about that @MariaBlair, that's just a matter of switching some the booleans around, but the same idea. I edited the answer. – Mark Jan 04 '19 at 00:57