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
-
Can the person who downvoted explain why? :)chevybow– chevybow2019年05月02日 21:08:12 +00:00Commented May 2, 2019 at 21:08
4 Answers 4
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'))
1 Comment
every()
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
Comments
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.
1 Comment
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));