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

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

本文关键字:for 循环 构建 函数 包含 reduce JavaScript      更新时间:2023-09-26

我想这是两个问题。我仍然在使用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 所说,对于这个特定问题,可能有一种更简单的方法,但你标记了这个"函数式编程",所以我想你想在这种解决问题的方式上做得更好,我完全赞同。

下面是一个 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.reduce相比,Array.prototype.some的最大优势是前者在条件true后立即退出迭代,而后者总是遍历整个数组。这意味着contains(4, xs)停止它与xs的第四个元素的迭代。

如何使用 YX

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

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

但是,如果您编写支持提前退出的reduce,则可以使用 reduce 解决方案。下面是将延续传递给回调的reducek。应用延续将继续减少,但返回值将执行提前退出。听起来完全像医生吩咐的...

这个答案是为了配合LUH3417的回答,告诉你在你意识到Array.prototype.some之前,你不应该坐在那里等待 ECMAScript 实现你需要的行为。这个答案表明您可以使用减少程序,并且仍然有提前退出行为。

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