Рассмотрим следующие массивы:

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

Я хочу написать метод, который наиболее эффективно проверяет, существуют ли в массиве и «a», и «b». Я знаю, что могу сделать это в простой цикл

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

Но это не очень коротко. Я могу сделать indexOf, но это будет повторяться дважды. Я также рассмотрел использование набора, как показано ниже:

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

Но я довольно незнаком с наборами и не знаю, может ли это решение быть более дорогим, чем просто зацикливание. Я знаю, что has() операции должны выполняться быстрее, чем итерации массива, но построение набора, вероятно, займет не менее O (N) времени (я предполагаю).

Есть ли чистый и эффективный способ найти несколько элементов в массиве? ES6 ответы приветствуются

1
chevybow 2 Май 2019 в 22:51

4 ответа

Лучший ответ

Вы можете использовать каждый и включает для выполнения этой проверки.

Итак, мы говорим, что каждый элемент должен быть включен в массив.

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'))
4
Get Off My Lawn 2 Май 2019 в 20:19

Вы можете использовать только Set и проверьте, есть ли нужные элементы в массиве items.

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
4
Nina Scholz 2 Май 2019 в 20:24

Не такой компактный, как другие примеры, но он делает работу за один проход.

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));
2
mbojko 2 Май 2019 в 20:05
array.includes('a') && array.includes('b')

includes кажется очень удобным способом проверки конкретных элементов, даже если их несколько.

2
AttemptedMastery 2 Май 2019 в 19:57