1

I need a fast way to find the one array in another.

The following example describes the scenario I have:

I need to find the array A:

var A = ["A0", "B0", "C0", "D2", "E2", "F0", "G2"];

In array B (please note, my B array may hold millions of results):

B[
["X0", "O0", "I0", "Z2", "T2", "L0", "V2"],
["I0", "V2", "O0", "T0", "L4", "X0", "Z3"],
["A0", "B0", "C0", "D2", "E2", "F0", "G2"],
["Z2", "L7", "T0", "I1", "V3", "X0", "O0"],
["Z3", "I1", "O0", "T3", "X0", "L2", "V2"],
["O0", "X0", "I1", "T2", "V0", "Z3", "L2"],
["I0", "Z0", "L7", "X0", "V3", "O0", "T3"],
["L3", "X0", "I1", "O0", "V0", "Z1", "T1"]
];

Is there a function that would either provide me with a true or false statement, or with an actual result which in the above case is: B[2]

jjj
  • 2,594
  • 7
  • 36
  • 57
  • does the order matters? is ther only one find inside? what have you tried? – Nina Scholz Jan 08 '18 at 12:24
  • Hi Nina, the order doesn't matter. All I want is to include array A in the array B, without duplicating it. So the idea is first to check that A is not occurring in B. – jjj Jan 08 '18 at 12:25
  • are ther duplicate entries in sub arrays, or in the find array? – Nina Scholz Jan 08 '18 at 12:30
  • Possible duplicate of [Search multi-dimensional array JavaScript](https://stackoverflow.com/questions/8809425/search-multi-dimensional-array-javascript) – Julien Ambos Jan 08 '18 at 12:30

4 Answers4

2

If you have no duplicates in the find array, you could use Array#findIndex with Array#every and Array#includes.

function getIndex(needle, haystack) {
    return haystack.findIndex(h => needle.every(n => h.includes(n)));
}

var a = ["A0", "B0", "C0", "D2", "E2", "F0", "G2"],
    b = [["X0", "O0", "I0", "Z2", "T2", "L0", "V2"], ["I0", "V2", "O0", "T0", "L4", "X0", "Z3"], ["A0", "B0", "C0", "D2", "E2", "F0", "G2"], ["Z2", "L7", "T0", "I1", "V3", "X0", "O0"], ["Z3", "I1", "O0", "T3", "X0", "L2", "V2"], ["O0", "X0", "I1", "T2", "V0", "Z3", "L2"], ["I0", "Z0", "L7", "X0", "V3", "O0", "T3"], ["L3", "X0", "I1", "O0", "V0", "Z1", "T1"]];
    
console.log(getIndex(a, b));
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
  • this seems to work... do you think it will perform well once the B array gets really large (hundreds of thousands or millions) of indexes? – jjj Jan 08 '18 at 12:48
  • @jjj, you could try it and if it is to slow, then you could use some nested for loops with early exit. – Nina Scholz Jan 08 '18 at 12:51
  • For now, I've decided to implement your method Nina, because the other recommended option is using JSON.stringify which I think adds a bit of complexity and may slow down the results. Once again, thank you very much. – jjj Jan 08 '18 at 12:53
1

If the order of items in A matters, then use find and JSON.stringify

var aStr = JSON.stringify( A );
var doesExists = !!B.find( s => JSON.stringify( s ) == aStr );

Demo

var B = [
["X0", "O0", "I0", "Z2", "T2", "L0", "V2"],
["I0", "V2", "O0", "T0", "L4", "X0", "Z3"],
["A0", "B0", "C0", "D2", "E2", "F0", "G2"],
["Z2", "L7", "T0", "I1", "V3", "X0", "O0"],
["Z3", "I1", "O0", "T3", "X0", "L2", "V2"],
["O0", "X0", "I1", "T2", "V0", "Z3", "L2"],
["I0", "Z0", "L7", "X0", "V3", "O0", "T3"],
["L3", "X0", "I1", "O0", "V0", "Z1", "T1"]
];
var A = ["A0", "B0", "C0", "D2", "E2", "F0", "G2"];

var aStr = JSON.stringify( A );
var doesExists = !!B.find( s => JSON.stringify( s ) == aStr );

console.log( doesExists );

And if the order doesn't matter then use sort as first before comparing.

var fnSort = (a,b) => a.localeCompare( b );
var aStr = JSON.stringify( A.sort( fnSort ) );
var doesExists = !!B.find( s => JSON.stringify( s.sort( fnSort ) ) == aStr );

Demo

var B = [
["X0", "O0", "I0", "Z2", "T2", "L0", "V2"],
["I0", "V2", "O0", "T0", "L4", "X0", "Z3"],
["A0", "B0", "C0", "D2", "E2", "F0", "G2"],
["Z2", "L7", "T0", "I1", "V3", "X0", "O0"],
["Z3", "I1", "O0", "T3", "X0", "L2", "V2"],
["O0", "X0", "I1", "T2", "V0", "Z3", "L2"],
["I0", "Z0", "L7", "X0", "V3", "O0", "T3"],
["L3", "X0", "I1", "O0", "V0", "Z1", "T1"]
];
var A = ["A0", "B0", "C0", "D2", "E2", "F0", "G2"];

var fnSort = (a,b) => a.localeCompare( b );
var aStr = JSON.stringify( A.sort( fnSort ) );
var doesExists = !!B.find( s => JSON.stringify( s.sort( fnSort ) ) == aStr );

console.log( doesExists );
gurvinder372
  • 66,980
  • 10
  • 72
  • 94
  • This is great, but I wonder about the performance of JSON.stringify on B array at the point when it contains million+ indexes. Can you contemplate about this? – jjj Jan 08 '18 at 12:47
  • @jjj For million+ indexes most approaches would struggle unless you **prep** the data and created indexes prior to the search.. Best way to check is to measure the performance based upon your own specific requirements of data. – gurvinder372 Jan 08 '18 at 12:50
  • Thanks a lot for all your help. – jjj Jan 08 '18 at 12:53
0

You could use find operator and compare if the array is included in and other array since arrays are objects you can't compare the directly, because they are different instances, to compare them you can try this trick converting them in strings...

var A = ["A0", "B0", "C0", "D2", "E2", "F0", "G2"];

var B = [
["X0", "O0", "I0", "Z2", "T2", "L0", "V2"],
["I0", "V2", "O0", "T0", "L4", "X0", "Z3"],
["A0", "B0", "C0", "D2", "E2", "F0", "G2"],
["Z2", "L7", "T0", "I1", "V3", "X0", "O0"],
["Z3", "I1", "O0", "T3", "X0", "L2", "V2"],
["O0", "X0", "I1", "T2", "V0", "Z3", "L2"],
["I0", "Z0", "L7", "X0", "V3", "O0", "T3"],
["L3", "X0", "I1", "O0", "V0", "Z1", "T1"],
["A0", "B0", "C0", "D2", "E2", "F0", "G2"]
];

function isIncluded(element) {
  return element.toString() == A.toString();
}

console.log(B.find(isIncluded)); // 130
Renzo Calla
  • 7,486
  • 2
  • 22
  • 37
0

Try something like this

var result = B.filter(function(bArr){ return bArr.length == A.length && bArr.every(function(ele,index){ return ele==A[index]})})
Jaydip Jadhav
  • 12,179
  • 6
  • 24
  • 40