可以在 Javascript 中使用 reduce 编写 bigram(或 ngram)函数吗?

Possible to write bigram (or ngram) function using reduce in Javascript?

我知道 Javascript 中的 .reduce 函数有一个 previouscurrent 变量的概念 "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 的工作方式是将一次调用的输出用作下一次调用的输入。如果我们将您的函数命名为 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 的答案一样。