使用我自己的 reduce 函数来检查数组交集

using my own reduce function to check array intersection

我想创建一个小应用程序,它可以检查数组的相交值,并在一个只有相交数字的新数组中减少这些数组。我能够使用内置原型方法来完成此操作,但想使用我自己定义的函数来完成。

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

由于 false 是从 currentValue 返回的,所以我非常困惑并且承认最近我越看这个越觉得我的解决方案没有意义。我缺少什么让我的 reduce 函数在这种情况下工作。

如果您想模拟 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]));

您可以尝试这种简单的方法,而无需使用 reduce。

看:

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]