@bozuriciyu

Как найти одинаковые значения в двух массивах?

const one = ['one', 'two', 'three', 'four', 'five']
const two = ['a', 'b', 'five', 'c', 'one']


Как эффективно найти повторяющиеся значения во втором массиве? Т.е. на выходе ['five', 'one']

Значений будет многовато, тысячи, хотелось бы эффективное решение.
  • Вопрос задан
  • 14976 просмотров
Решения вопроса 4
sergiks
@sergiks Куратор тега JavaScript
♬♬
Оптимизировать – непереоптимизировать!

Сортируем только короткий из двух. По длинному один раз и бинарным поиском в коротком.
let one = ['one', 'two', 'three', 'four', 'five'];
let two = ['a', 'b', 'five', 'c', 'one'];
const [long, short] = one.length > two.length ? [one,two] : [two,one];
short.sort();
const shortLength = short.length;

const binSearch = needle => {
  let start = 0, finish = shortLength - 1;
  while (start <= finish) {
    const center = Math.floor((start + finish) / 2);
    if (short[center] < needle) start = center + 1;
    else if (short[center] > needle) finish = center - 1;
    else return true;
  }
  return false;
}

const result = [];
for (let i = 0, length = long.length; i < length; i++)
  if (binSearch(long[i])) result.push(long[i]);

result // ["five","one"]


</Г-code>
Ответ написан
hahenty
@hahenty
('•')
Эффективнее пользоваться встроенными методами массивов, типа forEach или map, так как эти функции "заложены" в интерпретатор.

И могу предложить что-то такое

matched = one.filter( el => two.indexOf( el ) > -1 );
Ответ написан
longclaps
@longclaps
Эффективнее пользоваться встроенными в голову мозгами, при наличии.

Можно ручками написать слияние:
let one = ['one', 'two', 'three', 'four', 'five'];
let two = ['a', 'b', 'five', 'c', 'one'];
one.sort();
two.sort();
let i = one.length, j = two.length, three = [];
while (i > 0 && j > 0) {
    i--;
    j--;
    if (one[i] > two[j]) j++;
    else if (one[i] < two[j]) i++;
    else three.push(one[i]);
}
console.log(three);
Можно воспользоваться библиотекой:
const _ = require("lodash");
console.log(_.intersection(one, two));
Можно воспользоваться встроенным классом Set (пусть будет задание на дом).

ps Developer, увидишь Кнута - передавай привет.
Ответ написан
@rPman
Создаем на основе одного массива индекс (инвертируем ключи и значения), преобразуя массив в объект.
А затем простым перебором элементов второго массива проверяем наличие по ключу в инвертированным.

т.е. итоговая трудоемкость просто линейная (на самом деле там умноженное на логарифм но работа с ключами в javascript очень эффективна, на столько что этот логарифм вы заметите только на ОЧЕНЬ БОЛЬШИХ массивах, в крайнем случае можно использовать Map, он точно быстрый.
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
@fumitox84
Программист из сибири.
Можно так
function checkArrayIntersection(array1: string[], array2: string[]): boolean {
  return array1.some(item => array2.includes(item));
}

// Пример использования
const array1 = ["apple", "banana", "orange"];
const array2 = ["pear", "grape", "banana"];

const hasIntersection = checkArrayIntersection(array1, array2);

console.log(hasIntersection); // Выводит true, так как 'banana' есть в обоих массивах
Ответ написан
Комментировать
@Dichkin
gg
const filteredArray = one.filter(value => two.includes(value));
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы