user3206440
user3206440

Reputation: 5059

javascript - check if array contains any of another array of strings

strings_to_check = ["a", "b", "c"]

test_arrrays = [ [ "a", "c", "e", "g"], [ "v", "x", "y", "z"] ]

What is the right way to check if each array in test_arrays contains any of the strings in strings_to_check array - ie. a, b or c

I could do the following, but it has its downside that even if one of the strings is present, it still check's for the rest.

for(let i = 0; i < test_arrrays.length; i++){
  for(let j = 0; j < strings_to_check.length; j++){
      if(test_arrrays[i].indexOf(strings_to_check[j]) > -1) {
          console.log("matched");
      }
  }
}

Upvotes: 1

Views: 2069

Answers (4)

Vivick
Vivick

Reputation: 4991

If you only need to match one string just add break just like this :

for(/*loop settings*/){
  /*some code*/
  for(/*loop settings*/){
    /*some code*/
    if(/*some conditional statement*/){
      /*handling stuff*/
      break;
    }
  }
}

Upvotes: 0

le_m
le_m

Reputation: 20248

If you have multiple test_arrrays, it makes sense to convert the strings_to_check into a Set for constant time lookup. The overall time complexity then reduces from O(m n) to O(m + n log n) where n is the number of elements in strings_to_check and m is the total number of elements in all test_arrrays and O(n log n) is the Set setup time.

A generic check function would then look as follows:

// Check if each haystack contains at least one needle:
function check(needles, haystacks) {
  needles = new Set(needles);
  return haystacks.every(haystack => haystack.some(element => needles.has(element)));
}

// Example:
console.log(check(
  ["a", "b", "c"],
  [["a", "c", "e", "g"], ["v", "x", "y", "z"]]
));

Upvotes: 1

Alexander
Alexander

Reputation: 63399

This can be much more simply done with higher order functions, instead of devolving to using for loops and a slew of indices.

  1. We want to see if all test_arrrays elements meet some criteria, so we know we should use every:

    test_arrrays.every(/* some criteria */);
    
  2. Now we just have to find out what that criteria is. "contains any of the strings in strings_to_check" Sounds like we need to use some on test_array, to find out if any of its strings are contained in strings_to_check. So our "criteria" will be:

    test_arrray => test_arrray.some(s => strings_to_check_set.includes(s))
    

    putting it together, we get:

    test_arrrays.every( test_arrray => 
        test_arrray.some(s => strings_to_check_set.includes(s))
      )
    
  3. includes has linear time complexity, so we can improve this algorithm by using a Set, and replacing includes with has, which has constant time complexity., to obtain this final result:

    strings_to_check = ["a", "b", "c"]
    
    test_arrrays = [ [ "a", "c", "e", "g"], [ "v", "x", "y", "z"] ]
    
    strings_to_check_set = new Set(strings_to_check)
    
    test_arrrays.every(test_arrray =>
        test_arrray.some(s => strings_to_check_set.has(s))
    )
    

Upvotes: 2

kind user
kind user

Reputation: 41913

Assuming that you want to check if every array from test_arrays contains at least one element from the strings_to_check array, you could use mix of Array#every and Array#some functions.

var strings_to_check = ["a", "b", "c"],
    test_arrrays = [ [ "a", "c", "e", "g"], [ "v", "x", "y", "z"] ],
    res = test_arrrays.every(v => v.some(c => strings_to_check.indexOf(c) > -1));
    
    console.log(res);

Upvotes: 1

Related Questions