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

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

本文关键字:bigram ngram 函数 编写 reduce Javascript      更新时间:2023-09-26

我知道Javascript中的.reduce函数在其定义中具有"内置"previouscurrent变量的概念。所以我很好奇为什么这不起作用:

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来执行此操作吗?
  • 如果是这样,有没有另一种"功能性"方法可以做到这一点?
  • 如何避免这种嵌套行为?

reduce的工作方式是将一个调用的输出用作下一个调用的输入。 如果我们将您的函数命名为 f ,您的调用等效于:

f(f(f(f(0, 1), 2), 3), 4)

换句话说,previous并不意味着"原始数组中的上一项",而是表示"先前调用函数的结果"。

reduce不是此任务的好选择,因为顾名思义,它旨在将数组减少到单个值。 执行此操作的一种"功能"方法是使用 zip 并用数组尾部(除第一个元素之外的所有元素)压缩数组,如这个 Haskell 示例所示。 但是,Javascript没有内置zip函数。 使用此答案中的第二个zip实现:

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 中,我认为大多数人可能只是迭代地这样做,就像在回答这个问题时一样。