在问题Iterate a list as pair (current, next) in Python中,OP感兴趣的是将Python列表作为一系列current, next
对进行迭代。我也有同样的问题,但是我想用最干净的方式在JavaScript中解决这个问题,也许可以使用lodash。
使用一个简单的for
循环很容易做到这一点,但感觉并不是很优雅。
for (var i = 0; i < arr.length - 1; i++) {
var currentElement = arr[i];
var nextElement = arr[i + 1];
}
Lodash几乎可以做到这一点:
_.forEach(_.zip(arr, _.rest(arr)), function(tuple) {
var currentElement = tuple[0];
var nextElement = tuple[1];
})
在最后一次迭代中,nextElement
将是undefined
,这是一个微妙的问题。
当然,理想的解决方案应该是一个只在必要时循环的pairwise
lodash函数。
_.pairwise(arr, function(current, next) {
// do stuff
});
有没有现成的库已经这样做了?或者,有没有另一种我没有尝试过的在JavaScript中进行成对迭代的好方法?
说明:如果为arr = [1, 2, 3, 4]
,则我的pairwise
函数将按如下方式迭代:[1, 2]
,[2, 3]
,[3, 4]
,而不是[1, 2]
,[3, 4]
。这就是操作员在the original question for Python中询问的内容。
发布于 2015-08-13 03:11:20
只需将“丑陋”的部分变成一个函数,然后它就会看起来很好:
arr = [1, 2, 3, 4];
function pairwise(arr, func){
for(var i=0; i < arr.length - 1; i++){
func(arr[i], arr[i + 1])
}
}
pairwise(arr, function(current, next){
console.log(current, next)
})
您甚至可以稍微修改它,使其能够迭代所有i,i+n对,而不仅仅是下一个:
function pairwise(arr, func, skips){
skips = skips || 1;
for(var i=0; i < arr.length - skips; i++){
func(arr[i], arr[i + skips])
}
}
pairwise([1, 2, 3, 4, 5, 6, 7], function(current,next){
console.log(current, next) // displays (1, 3), (2, 4), (3, 5) , (4, 6), (5, 7)
}, 2)
发布于 2015-11-08 03:31:40
在Ruby中,这称为each_cons
(每个连续):
(1..5).each_cons(2).to_a # => [[1, 2], [2, 3], [3, 4], [4, 5]]
它是proposed for Lodash,但被拒绝了;但是,在npm上有一个each-cons模块:
const eachCons = require('each-cons')
eachCons([1, 2, 3, 4, 5], 2) // [[1, 2], [2, 3], [3, 4], [4, 5]]
在Ramda中还有一个aperture
函数,它做同样的事情:
const R = require('ramda')
R.aperture(2, [1, 2, 3, 4, 5]) // [[1, 2], [2, 3], [3, 4], [4, 5]]
发布于 2018-01-31 19:41:08
这个答案的灵感来自于我在Haskell中看到的一个类似问题的答案:https://stackoverflow.com/a/4506000/5932012
我们可以使用Lodash中的帮助器来编写以下代码:
const zipAdjacent = function<T> (ts: T[]): [T, T][] {
return zip(dropRight(ts, 1), tail(ts));
};
zipAdjacent([1,2,3,4]); // => [[1,2], [2,3], [3,4]]
(与Haskell的等价物不同,我们需要dropRight
,因为Lodash的zip
的行为与Haskell的`不同:它将使用最长数组的长度,而不是最短数组的长度。)
Ramda也是如此:
const zipAdjacent = function<T> (ts: T[]): [T, T][] {
return R.zip(ts, R.tail(ts));
};
zipAdjacent([1,2,3,4]); // => [[1,2], [2,3], [3,4]]
尽管Ramda已经有一个名为aperture的函数来解决这一问题。这稍微更通用一些,因为它允许您定义想要的连续元素的数量,而不是缺省为2:
R.aperture(2, [1,2,3,4]); // => [[1,2], [2,3], [3,4]]
R.aperture(3, [1,2,3,4]); // => [[1,2,3],[2,3,4]]
https://stackoverflow.com/questions/31973278
复制相似问题