如何在 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
我想这是两个问题。我仍然无法使用 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