используя мою собственную функцию Reduce для проверки пересечения массива - PullRequest
1 голос
/ 24 января 2020

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

const forEach = (array, callback) => {
  for (var i = 0; i < array.length; i++) {
    callback(array[i])
  }
}
const reduce = (array, callback, initValue) => {
  accumulator = initValue
  const reduceFunction = (el) => {
    accumulator += callback(el)
  }
  forEach(array, reduceFunction)
  return accumulator
}
const intersectionWithReduce = (...arrays) => {
  currentValue = []
  reduce(arrays, el => currentValue += arrays.filter(currentValue.includes(el)), currentValue)
  return currentValue
}

console.log(intersectionWithReduce([1, 2, 3, 20], [15, 88, 1, 2, 7], [1, 10, 3, 2, 5, 20]));
// expected output of [1,2]
// actual output TypeError: false is not a function

Поскольку из currentValue возвращается false, я запутался и признаю, что в последнее время, чем больше я смотрю на это, тем больше я чувствую, что мои решения не имеют смысла , Чего мне не хватает, чтобы моя функция приведения работала в этом контексте.

Ответы [ 2 ]

1 голос
/ 24 января 2020

Если вы хотите эмулировать функциональность reduce, вызовите callback с (как минимум) двумя аргументами: текущим аккумулятором и текущим итерируемым элементом. Затем присвойте результат accumulator и продолжайте до тех пор, пока массив не будет полностью повторен.

Поскольку вы хотите найти пересечение здесь, вероятно, было бы разумнее передать , а не начальное значение - вернее, по умолчанию первый элемент массива используется в качестве аккумулятора (точно так же, как это делает Array.prototype.reduce), и на каждой итерации вызывайте .filter для аккумулятора, проверяя, содержит ли другой массив элемент:

const reduce = (array, callback, initValue) => {
  let i = 0;
  let accumulator = initValue !== undefined ? initValue : (i++, array[0]);
  for (; i < array.length; i++) {
    accumulator = callback(accumulator, array[i]);
  }
  return accumulator;
}
const intersectionWithReduce = (...arrays) => {
  return reduce(arrays, (accum, arr) => accum.filter(accumItem => arr.includes(accumItem)));
}

console.log(intersectionWithReduce([1, 2, 3, 20], [15, 88, 1, 2, 7], [1, 10, 3, 2, 5, 20]));
0 голосов
/ 24 января 2020

Вы можете попробовать этот простой подход без необходимости использовать Reduce.

Look:

const intersectionWithReduce = (...arrays) => (
  arrays.map(arrElm => // array of arrays, arrays[0] = [1, 2, 3, 20]
    arrElm.filter(arrElm => // filtering for equals
      arrays.every(elm => 
        elm.includes(arrElm) // only evaluate if this item is present in every other array
      )
    )
  )[0] 
)
/*  /\
 * Here it's [0] because doesn't matter the position, 
 * all the remaining arrays will be the same. 
 * In this case without this part the result would be [[1, 2], [1, 2], [1, 2]]
*/

console.log(intersectionWithReduce([1, 2, 3, 20], [15, 88, 1, 2, 7], [1, 10, 3, 2, 5, 20]))
// output [1, 2]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...