如何在 JavaScript 中使用 reduce 而不是 for 循环构建包含函数?

How do I build a contains function using reduce instead of a for loop in JavaScript?

我想这是两个问题。我仍然无法使用 reduce 方法,我得到了使用它的简单方法

reduce([1,2,3], function(a, b) { return a + b; }, 0); //6

将它与数字以外的任何东西一起使用真的让我感到困惑。那么我如何使用 reduce 代替 for 循环来构建一个包含函数呢?评论将不胜感激。谢谢大家

function contains(collection, target) {
  for(var i=0; i < collection.length; i++){
    if(collection[i] === target){
      return true;
    }
  }
  return false;
}
contains([1, 2, 3, 4, 5], 4);
//true

这就是你需要的:

function contains(collection, target) {
    return collection.reduce( function(acc, elem) {
       return acc || elem == target;
    }, false)
};

正如 adaneo 所说,对于这个特定问题可能有更简单的方法,但是你标记了这个 'functional programming' 所以我猜你想在这种解决问题的方法上做得更好,我完全赞同。

这是一个 ES2015 解决方案:

    const contains = (x, xs) => xs.some(y => x === y);
    let collection = [1,2,3,4,5];

    console.log(contains(4, collection)); // true;

Array.prototype.some相比Array.prototype.reduce最大的优势在于前者只要条件为true就退出迭代,而后者总是遍历整个数组。这意味着 contains(4, xs) 停止它与 xs.

的第四个元素的迭代

How do I do X using Y ?

通常我以相同的方式处理所有这些问题:编程语言并不意味着是魔杖。如果您的语言没有内置功能或行为,您应该能够自己编写。从那里,如果您后来了解到您的语言 确实 为这种行为提供了内置(或添加),那么您可以根据需要重构您的代码。但无论如何,不​​要坐等魔杖被挥动,等待你的代码神奇地工作。

如果需要,您 可以 使用 Array.prototype.reduce,但考虑到它的工作方式,它将始终遍历数组的全部内容——即使匹配在第一个元素中找到。所以这意味着你不应该为你的函数使用Array.prototype.reduce

但是,您可以使用减少解决方案 如果 您编写了支持提前退出的 reduce。下面是 reducek,它将延续传递给回调。应用延续将继续减少,但返回一个值将执行提前退出。听起来正是医生的要求...

这个答案是为了伴随 LUH3417 的答案向您展示在您可能意识到 Array.prototype.some 之前,您不应该坐在那里等待 ECMAScript 实现您需要的行为。 This answer demonstrates you can use a reducing procedure and still have early exit behavior.

const reducek = f=> y=> ([x,...xs])=>
  x === undefined ? y : f (y) (x) (y=> reducek (f) (y) (xs))

const contains = x=>
  reducek (b=> y=> k=> y === x ? true : k(b)) (false)

console.log(contains (4) ([1,2,3,4,5])) // true
console.log(contains (4) ([1,2,3,5]))   // false
console.log(contains (4) ([]))          // false

看到这里的 reducek 和示例 contains 函数,应该可以看出 contains 可以泛化,这正是 Array.prototype.some 的意思。

再说一次,编程不是魔法,所以我将向您展示如果 Array.prototype.some 尚不存在,您可以如何做到这一点。

const reducek = f=> y=> ([x,...xs])=>
  x === undefined ? y : f (y) (x) (y=> reducek (f) (y) (xs))

const some = f=>
  reducek (b=> x=> k=> f(x) ? true : k(b)) (false)

const contains = x=> some (y=> y === x)

console.log(contains (4) ([1,2,3,4,5])) // true
console.log(contains (4) ([1,2,3,5]))   // false
console.log(contains (4) ([]))          // false