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]

4
  • does the order matters? is ther only one find inside? what have you tried? Commented Jan 8, 2018 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. Commented Jan 8, 2018 at 12:25
  • are ther duplicate entries in sub arrays, or in the find array? Commented Jan 8, 2018 at 12:30
  • Possible duplicate of Search multi-dimensional array JavaScript Commented Jan 8, 2018 at 12:30

4 Answers 4

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));

Sign up to request clarification or add additional context in comments.

3 Comments

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, you could try it and if it is to slow, then you could use some nested for loops with early exit.
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.
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 );

3 Comments

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 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.
Thanks a lot for all your help.
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

Comments

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]})})

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.