1
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");
 }
 }
}
asked May 1, 2017 at 17:47
1
  • 1
    let test = test_arrays.every(a => a.some(s => strings_to_check.includes(s)));. Commented May 1, 2017 at 17:51

4 Answers 4

2

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))
    )
    
answered May 1, 2017 at 18:01

4 Comments

Unfortunately your function returns a wrong result.
@Kinduser username checks out. Does it? What was your test case?
I guess you should replace your first some function with every, because as for now, it will return true even if only one array fulfills the condition (contains any item from strings_to_check array).
@Kinduser Oh, I misunderstood the question. Fixing it now
1

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

answered May 1, 2017 at 17:52

Comments

1

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

answered May 1, 2017 at 18:12

Comments

0

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;
 }
 }
}
marc_s
759k185 gold badges1.4k silver badges1.5k bronze badges
answered May 1, 2017 at 17:52

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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.