JavaScript: используйте Reduce () для создания пересечения функций, которое сравнивает входные массивы;вернуть только пересекающиеся элементы - PullRequest
0 голосов
/ 14 июня 2019

Создает пересечение функций, которое сравнивает входные массивы и возвращает новый массив с элементами, найденными во всех входных данных.

Мое решение работает, но оно очень громоздко:

const intersection = (arrMerged) => {

  let finalArr = []; 
  let flatArray = [].concat(...arrMerged)

  let newArr = []; 
  //console.log(flatArray)

  //let interArray = []; 

  if (arrMerged[2] !== undefined){

    newArr = arrMerged[0].map((elem) => {
      if (arrMerged[1].includes(elem) && arrMerged[2].includes(elem)){
        return elem; 
      }
    })
  }

  else {
    newArr = arrMerged[0].map((elem) => {
      if (arrMerged[1].includes(elem)){
        return elem; 
      }
    })
  }


  newArr.forEach((elem) => {
    if (elem !== undefined){
      finalArr.push(elem)
    }
  })
  return finalArr; 
}

// Uncomment these to check your work!
const arr1 = [5, 10, 15, 20];
const arr2 = [15, 88, 1, 5, 7];
const arr3 = [1, 10, 15, 5, 20];

console.log(intersection([arr1, arr2, arr3])); // should log: [5, 15]

Я также хотел бы использовать Reduce () в моем решении. Может ли кто-нибудь предоставить альтернативное решение для кода, которое использует redu () и является более эффективным, пожалуйста?

Буду признателен, если вы прокомментируете, что делает каждая строка вашего кода, чтобы помочь мне понять.

Ответы [ 3 ]

2 голосов
/ 14 июня 2019

Вы можете использовать reduce следующим образом:

const intersection = (arrays) =>
    arrays.reduce((a, b) =>
        a.filter(c => b.some(d => c === d)) 
    );

Часть filter выполняет пересечение двух заданных массивов a и b.Часть reduce применяет эту логику, беря следующий массив из входных данных и пересекая его с предыдущим результатом.

Однако это не самый оптимальный способ.Используйте Set для повышения производительности при использовании огромных массивов.

const intersection = (arrays) =>
    arrays.reduce((a, b) => {
        const set = new Set(b);
        return a.filter(c => set.has(c)); 
    });

Подробнее об этом см. Ответ на этот вопрос - в качестве входных данных используются только два массива.

0 голосов
/ 14 июня 2019

Вы можете взять первый индексный массив и сопоставить его с любым другим массивом и значением фильтра, основанным соответственно

const arr1 = [5, 10, 15, 20];
const arr2 = [15, 88, 1, 5, 7];
const arr3 = [1, 10, 15, 5, 20];

const intersection = (arr) => {
  let [a,...rest] = arr
  return a.filter(v=> rest.every(val => val.includes(v)))
}

console.log(intersection([arr1, arr2, arr3]));
0 голосов
/ 14 июня 2019

Вы можете использовать filter() на любом подмассиве. И используйте вложенный every() в основном массиве.

const arr1 = [5, 10, 15, 20];
const arr2 = [15, 88, 1, 5, 7];
const arr3 = [1, 10, 15, 5, 20];

const intersection = arr => arr[0].filter(x => arr.every(a => a.includes(x)));

console.log(intersection([arr1,arr2,arr3]))

Пояснение:

См. Код:

arr[0].filter(x => arr.every(a => a.includes(x)));

Слово, объясняющее эту волю. Он отфильтровывает только те элементы первого подмассива (arr[0]), которые включены в любой другой подмассив.

Array.prototype.every() принимает обратный вызов в качестве параметра. Первым элементом обратного вызова будет сам элемент. В приведенном выше случае a будет arr1,arr2,arr3.

arr.every(a => a.includes(x)) проверяет наличие текущего элемента первого массива. 5,10,15,20 присутствует во всех других массивах

В указанной версии есть вложенные циклы. Если вам нужно более эффективное решение, вы можете сначала преобразовать все массивы, кроме сначала, в Set, а затем использовать Set.has

const arr1 = [5, 10, 15, 20];
const arr2 = [15, 88, 1, 5, 7];
const arr3 = [1, 10, 15, 5, 20];

const intersection = arr => {
  let [first,...rest] = arr;
  rest = rest.map(x => new Set(x));
  return first.filter(x => rest.every(a => a.has(x)));


} 
console.log(intersection([arr1,arr2,arr3]))
...