如何使用具有前一个值和当前值的underscore.js迭代数组?

时间:2013-12-28 17:31:39

标签: javascript algorithm iteration underscore.js

是否有任何简单神奇的下划线(lo-dash)功能组合来实现以下算法:

var arr = [1, 4, 9, 16, 25];
var result = [];
for(var i = 1, len = arr.length; i < len; ++i) {
    var current = arr[i];
    var previous = arr[i-1];
    result[i-1] = current - previous;
}
// result == [3, 5, 7, 9]

语法更简单:

var arr = [1, 4, 9, 16, 25];
var result = _.???(arr, function(current, previous) {
    return current - previous;
}

注意:

  1. 我不想自己动手,我宁愿使用现有方法的组合。
  2. 显然我的数组包含对象而不是数字,结果可能是也可能不是数字列表。

2 个答案:

答案 0 :(得分:4)

只需使用_.map()并使用i及其为您提供的集合。

var arr = [1, 4, 9, 16, 25];
var result = _.map(arr, function(curr, i, arr) {
    return i ? curr - arr[i-1] : null;
}).slice(1);

我在第一次迭代中返回null,然后在最后将其切掉。

http://jsfiddle.net/8aZnp/


技术上_.reduce()可以为您提供最后和当前项目,如果您始终返回当前项目。这是使用_.reduce的一种hackish方式,但它有效。

var arr = [1, 4, 9, 16, 25];
var result = [];
_.reduce(arr, function (last, curr) {
    result.push(curr - last);
    return curr;
});

http://jsfiddle.net/8aZnp/1/

答案 1 :(得分:1)

我想出的另一种方法是:

var arr = [1, 4, 9, 16, 25];
_.map(_.zip(_.rest(arr , 1), _.first(arr, arr.length - 1)), function(pair) {
    var current = pair[0];
    var previous = pair[1];
    return current - previous;
});

但是这个解决方案是O(4n)(给定mapziprestfirst是线性的)并且非常详细。