0

I have 2 Arrays. How can I check if Array 2 is in Array 1 and how can I find the index of the first Array.

0: (2) ['pik13', 'karo10']
1: ['karo14']
2: ['karo11']
3: (2) ['karo6', 'pik10']
4: ['herz10']
5: (3) ['pik11', 'kreuz10', 'kreuz11']
0: (3) ['pik11', 'kreuz10', 'kreuz11']

These are the 2 Arrays. The expected output should be 5.

1
  • Does the order of the items in the array matter? Commented Apr 18, 2022 at 20:23

3 Answers 3

1

If the order does not matter you can use the following:

const searchIn = [
  ["pik13", "karo10"],
  ["karo14"],
  ["karo11"],
  ["karo6", "pik10"],
  ["herz10"],
  ["pik11", "kreuz10", "kreuz11"],
];

const searchFor = ["pik11", "kreuz10", "kreuz11"];

/**
 * Check if the the elements in an array matches the elements in the Set
 * @param {Array} array
 * @param {Set} toBeFound
 * @returns
 */
function compareArray(array, toBeFound) {
  // early outs it the element is not an array or the length does not match
  if (!Array.isArray(array) || array.length !== toBeFound.size) return false;
  // finds match in O(n) due fast lookup in Set
  return array.every((item) => toBeFound.has(item));
}

/**
 * Search for array in array.
 * @param {Array} toBeSearched
 * @param {Array} toBeFound
 * @returns
 */
function searchForArray(toBeSearched, toBeFound) {
  // use a set to make the lookups faster => O(1)
  const elements = new Set(toBeFound);
  return toBeSearched.findIndex((array) => compareArray(array, elements));
}

console.log(searchForArray(searchIn, searchFor));
This uses a Set to speed up the lookup when comparing array values to O(1) in contrast to using includes() which will result in a worst case lookup runtime of O(n). By reason of this the worst case runtime for compareArray() is O(n) instead of O(n²). In most cases it will even be significantly faster as for instance in your example there is only one array which matches in length with the array we search for, so that we only compare the array values once. Overall in worst case the algorithm will take O(m * n) where m is the number of arrays to search and n is the number of elements in the array we are looking for.

This will not work if you search for nested arrays, but can made to work with some changes for deep comparisons.

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

Comments

1

If the order DOES matter....

let arr =[['pik13', 'karo10'],['karo14'],['karo11'],['karo6', 'pik10'],['herz10'],['pik11', 'kreuz10','kreuz11'],];
let compare = ['pik11', 'kreuz10', 'kreuz11'];
let index = arr.findIndex(x => JSON.stringify(x)===JSON.stringify(compare)); 
// This could also for a bit more speed use String(x) === String(compare) as @Thomas notes in the below comments

console.log(index);

As pointed out in the comments, JSON.Stringify can be very slow, for small array's and non-intensive calculations it's probably fine, so here's a faster method for 1 for 1 comparing that doesn't convert the array to a string:

let arr =[['pik13', 'karo10'],['karo14'],['karo11'],['karo6', 'pik10'],['herz10'],['pik11', 'kreuz10', 'kreuz11']];
let compare = ['karo6', 'pik10'];
let index = arr.findIndex(x => x.length === compare.length && x.every((v,i)=> compare[i] === v));

console.log(index);

If the order DOESN'T matter...

let arr =[['pik13', 'karo10'],['karo14'],['karo11'],['karo6', 'pik10'],['herz10'],['pik11', 'kreuz10', 'kreuz11']];
let compare = ['kreuz10', 'kreuz11', 'pik11'];
let index = arr.findIndex(x => x.length === compare.length && x.every((i)=> compare.includes(i)));

console.log(index);

3 Comments

the order does not matter, but this solution is perfect for me thanks
String(x) === String(compare) is faster, cheaper and sufficient. And if order doesn't matter, it would be the simplest to keep the sub-arrays all sorted.
Yes @Thomas, it would indeed, I always overlook a direct String conversion.
0

You can use JSON.stringify for array equality and findIndex to get the result index.

const array2D = [['pik13', 'karo10'],['karo14'],['karo11'],['karo6', 'pik10'],['herz10'],['pik11', 'kreuz10', 'kreuz11']]

const subjectArray1D = ['pik13', 'karo10'];

const result = array2D.findIndex((array1D) => {
  return JSON.stringify(array1D) === JSON.stringify(subjectArray1D);
});

console.log(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.