可以在 Javascript 中使用 reduce 编写 bigram(或 ngram)函数吗?
Possible to write bigram (or ngram) function using reduce in Javascript?
我知道 Javascript 中的 .reduce
函数有一个 previous
和 current
变量的概念 "built-in",可以这么说,在它的定义中.所以我很好奇为什么这不起作用:
var bigrams = [0, 1, 2, 3, 4].reduce(function(previous, current) {
return [previous, current]
});
我认为这不是我认为的意思,因为现在 bigrams
包含:
[[[[0,1],2],3],4]
当我想要的是:
[[0,1],[1,2],[2,3],[3,4]]
我认为这与结果应该被推入累加器这一事实有关(它可能应该是一个空数组,比如:arr.reduce(/*magic*/, [])
?
- 我不应该使用
.reduce
来执行此操作吗?
- 如果是这样,还有其他 "functional" 方法吗?
- 如何避免这种嵌套行为?
reduce 的工作方式是将一次调用的输出用作下一次调用的输入。如果我们将您的函数命名为 f
,您的调用相当于:
f(f(f(f(0, 1), 2), 3), 4)
也就是说previous
不是"previous item in the original array",而是"result of the previous call to the function"。
reduce
不是这个任务的好选择,因为正如其名称所暗示的那样,它旨在 将数组减少 为单个值。一种 "functional" 方法是使用 zip
并用尾部压缩数组(除第一个元素外的所有元素),如 this Haskell example. However, Javascript doesn't have a zip function builtin. Using the second zip
implementation from this answer:
所示
function zip() {
var args = [].slice.call(arguments);
var shortest = args.length==0 ? [] : args.reduce(function(a,b){
return a.length<b.length ? a : b
});
return shortest.map(function(_,i){
return args.map(function(array){return array[i]})
});
}
你可以这样做:
var x = [0, 1, 2, 3, 4]
zip(x, x.slice(1))
但是,在 JavaScript 中,我认为大多数人可能只是反复地做,就像 this question 的答案一样。
我知道 Javascript 中的 .reduce
函数有一个 previous
和 current
变量的概念 "built-in",可以这么说,在它的定义中.所以我很好奇为什么这不起作用:
var bigrams = [0, 1, 2, 3, 4].reduce(function(previous, current) {
return [previous, current]
});
我认为这不是我认为的意思,因为现在 bigrams
包含:
[[[[0,1],2],3],4]
当我想要的是:
[[0,1],[1,2],[2,3],[3,4]]
我认为这与结果应该被推入累加器这一事实有关(它可能应该是一个空数组,比如:arr.reduce(/*magic*/, [])
?
- 我不应该使用
.reduce
来执行此操作吗? - 如果是这样,还有其他 "functional" 方法吗?
- 如何避免这种嵌套行为?
reduce 的工作方式是将一次调用的输出用作下一次调用的输入。如果我们将您的函数命名为 f
,您的调用相当于:
f(f(f(f(0, 1), 2), 3), 4)
也就是说previous
不是"previous item in the original array",而是"result of the previous call to the function"。
reduce
不是这个任务的好选择,因为正如其名称所暗示的那样,它旨在 将数组减少 为单个值。一种 "functional" 方法是使用 zip
并用尾部压缩数组(除第一个元素外的所有元素),如 this Haskell example. However, Javascript doesn't have a zip function builtin. Using the second zip
implementation from this answer:
function zip() {
var args = [].slice.call(arguments);
var shortest = args.length==0 ? [] : args.reduce(function(a,b){
return a.length<b.length ? a : b
});
return shortest.map(function(_,i){
return args.map(function(array){return array[i]})
});
}
你可以这样做:
var x = [0, 1, 2, 3, 4]
zip(x, x.slice(1))
但是,在 JavaScript 中,我认为大多数人可能只是反复地做,就像 this question 的答案一样。