【问题标题】:The use of first last and map to implement Reduce使用first last和map实现Reduce
【发布时间】:2016-12-21 05:49:31
【问题描述】:

我偶然发现了这段代码,旨在重新定义 Array.prototype.reduce:

function first(array, n){
  return n === undefined ? array[0] : array.slice(0, n);
}; 

function last(array, n){
  if(n> array.length){
    return array;
    }else{
      return n === undefined ? array[array.legnth -1] : array.slice(array.length - n, array.length);
      
};
  
  function map(collection, iterator){
    var arr = []; 
    each(collection, function(element, index){
      arr.push(iterator(element, index);
    });
     return arr;
  };
function reduce(collection, rf, acc) {
    acc = acc === undefined ? first(collection) : acc;
    return last(map(collection, function (value) {
        acc = rf(acc, value);
        return acc;
    }));
}

但是,我不明白 array.last() 在这里做什么。有人可以解释一下。谢谢你。

【问题讨论】:

  • 数组没有原生的last函数。除非它也是数组原型的扩展。根据您的代码,没有array.last() 调用,我只能看到last 函数。最后做的是在那个 javascript 范围本身中实现的。你可以自己找。
  • last 定义在哪里
  • 您必须向我们展示first()last()map() 函数,因为它们不是标准的Javascript。我们可以猜到他们做了什么,但如果我们不必猜测,这里的答案会好得多。此外,您询问了array.last(),但您的代码中没有类似的内容。请花一些时间编写/编辑一个清晰的问题,其中包含所有必要的信息,以了解您的问题以及您的情况。现在,这个问题将被关闭为“不清楚你在问什么”,因为其中没有足够的信息。
  • @jfriend00 感谢您的所有 cmets。我已添加您要求的信息。感谢您查看此内容。
  • last()length 在这一行拼写错误:array[array.legnth -1]

标签: javascript arrays object methods


【解决方案1】:
0:    function reduce(collection, rf, acc) {
1:        acc = acc === undefined ? first(collection) : acc;
2:        return last(map(collection, function (value) {
3:            acc = rf(acc, value);
4:            return acc;
5:        }));
6:    }

以下是您的 reduce() 函数中发生的逐行说明:

第 1 行:如果没有为 acc 传递值,则将其设置为集合中的第一个值。

第 2 行:在您的集合上调用 map(),这将遍历该集合,并在集合的每个项目上调用一个调用 rf() 的回调。 map() 创建一个新数组,该数组是每次调用迭代回调时返回值的集合。在从 map() 返回的结果数组上,从该数组中获取 last() 值并将其作为最终返回结果从 reduce() 返回。

第 3 行:将 acc 设置为 rf(acc, value) 的结果。

第 4 行:从 map() 将放入数组的回调中返回 acc

但是,我不明白 array.last() 在这里做什么。能 有人请解释一下。

假设您的意思是last(array),您的last(array) 的功能是获取数组中的最后一项。如果您将第二个参数传递给 last(),那么它会从您传入的数组中获取最后 N 项并将其作为新数组返回(您没有使用第二个功能)。


reduce() 的实现似乎不应该使用map(),因为创建这个内部数组没有意义。我认为这会更有效:

function reduce(collection, rf, initial) {
    var acc = (initial === undefined) ? first(collection) : initial;
    each(collection, function(value) {
        acc = rf(acc, value);
    });
    return acc;
}

如果您想更准确地模仿Array.prototype.reduce(),其中如果没有选择初始值,则将数组中的第一个元素用作初始值并且不为数组中的第一个元素调用迭代器,那么您可以这样做:

function reduce(collection, rf, initial) {
    var acc = initial, index = 0;
    if (initial === undefined) {
        acc = collection[0];
        index = 1;
    }
    for (; index < collection.length; ++index) {
        acc = rf(acc, collection[index]);
    });
    return acc;
}

【讨论】:

  • 非常感谢您花时间解释它。我同意。当您已经有回调时,此处使用 map 似乎是多余且不必要的。使用 each 似乎是实现它的理想方式。
  • 快速问题 - 如果您正在迭代整个集合,那么集合 [0] 不会。迭代两次?
  • @IvonneTerrero - 是的,它会的。这不是 Javascript 的 Array.prototype.reduce() 的行为,但您没有提供所需行为的规范,所以我没有更改它的这方面。
  • @IvonneTerrero - 由于您可能是这里的新手,如果这回答了您的问题,那么您可以通过单击最佳答案旁边的绿色复选标记向社区表明这一点。遵循正确的程序,这也将为您赢得一些声誉积分。
  • @IvonneTerrero - 我添加了一个替代实现。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-21
  • 2020-10-11
  • 1970-01-01
  • 2015-07-07
  • 2021-07-17
  • 2011-10-05
相关资源
最近更新 更多