3

Consider the following arrays:

['a', 'b', 'a'] //method should return true
['a', 'b', 'c'] //method should return true
['a', 'c', 'c'] //method should return false

I want to write a method that most efficiently checks to see if both 'a' and 'b' exist in the array. I know I can do this in a simple for loop

let a_counter = 0;
let b_counter = 0;
for (let i = 0; i < array.length; i++) {
 if (array[i] === 'a') {
 a_counter++;
 }
 if (array[i] === 'b') {
 b_counter++;
 }
}
return (a_counter > 0 && b_counter > 0);

But this isn't very short. I can do indexOf but that will loop through twice. I have also considered using a set as below:

const letter_set = new Set(array)
return (letter_set.has('a') && letter_set.has('b')) 

But I am pretty unfamiliar with sets and don't know if this solution could potentially be more expensive than just looping. I know that has() operations should be faster than array iterations but constructing the set probably takes at least O(N) time (I'm assuming).

Is there a clean and efficient way to find multiple elements in an array? ES6 answers welcome

asked May 2, 2019 at 19:51
1
  • Can the person who downvoted explain why? :) Commented May 2, 2019 at 21:08

4 Answers 4

6

You can use every and includes to do this check.

So we are saying every item must be included in the array.

function contains(arr, ...items) {
 return items.every(i => arr.includes(i))
}
console.log(contains(['a', 'b', 'a'], 'a', 'b'))
console.log(contains(['a', 'c', 'c'], 'a', 'b'))
console.log(contains(['a', 'b', 'c'], 'a', 'b', 'c'))
console.log(contains(['a', 'b', 'c', 'd'], 'a', 'b', 'c', 'd', 'e'))

answered May 2, 2019 at 19:56

1 Comment

I really like the readability of this answer. For some reason I didn't consider using every()
3

You could use just the Set and check if the wanted items are in the items array.

const
 check = (items, wanted) => wanted.every(Set.prototype.has, new Set(items));
console.log(check(['a', 'b', 'a'], ['a', 'b'])); // true
console.log(check(['a', 'b', 'c'], ['a', 'b'])); // true
console.log(check(['a', 'c', 'c'], ['a', 'b'])); // false

answered May 2, 2019 at 19:55

Comments

2
array.includes('a') && array.includes('b')

includes seems like a real handy way to check for specific elements, even if there is more than one.

answered May 2, 2019 at 19:55

1 Comment

@NinaScholz I made an edit for another test case. I don't mind if there's other elements (at least for the current function I'm working on)
2

Not as compact as the other examples, but it does do the job in single run.

const arr1 = ['a', 'b', 'a']; //method should return true
const arr2 = ['a', 'c', 'c']; //method should return false
const arr3 = ['a', 'b', 'c']; //method should return true
const reducer = ({ a, b }, char) => ({
 a: a || char === 'a',
 b: b || char === 'b'
});
const includesAnB = arr => {
 const { a, b } = arr.reduce(reducer, {});
 return a && b;
}
console.log(includesAnB(arr1));
console.log(includesAnB(arr2));
console.log(includesAnB(arr3));

answered May 2, 2019 at 20:05

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.