在JavaScript中,以一个对(当前,下一个)的形式迭代一个数组。
在JavaScript中,以一个对(当前,下一个)的形式迭代一个数组。
在问题Iterate a list as pair (current, next) in Python中,提问者想要在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) { // 做一些事情 });
是否有任何现有的库已经实现了这个功能?或者是否有其他我尚未尝试过的以配对方式迭代的JavaScript好方法?
澄清:如果arr = [1, 2, 3, 4]
,那么我的pairwise
函数将按如下方式迭代:[1, 2]
,[2, 3]
,[3, 4]
,而不是[1, 2]
,[3, 4]
。这就是提问者在原始问题中针对Python所询问的内容。
在JavaScript中,有时需要以一对一对的方式迭代数组。这种需求在Ruby中被称为"each_cons"(每个连续的元素)。
Ruby中的示例代码如下:
(1..5).each_cons(2).to_a // => [[1, 2], [2, 3], [3, 4], [4, 5]]
有人提议在Lodash中加入类似的功能,但被拒绝。不过,在npm上有一个名为"each-cons"的模块可以实现这个功能。
在使用该模块之前,需要先安装它:
const eachCons = require('each-cons')
然后,可以使用eachCons函数来实现数组的一对一对迭代:
eachCons([1, 2, 3, 4, 5], 2) // [[1, 2], [2, 3], [3, 4], [4, 5]]
除了each-cons模块,Ramda库中也提供了一个名为"aperture"的函数,可以实现相同的功能。
首先,需要安装Ramda库:
const R = require('ramda')
然后,可以使用aperture函数来实现数组的一对一对迭代:
R.aperture(2, [1, 2, 3, 4, 5]) // [[1, 2], [2, 3], [3, 4], [4, 5]]
以上就是解决在JavaScript中实现数组的一对一对迭代的方法。无论是使用each-cons模块还是Ramda库中的aperture函数,都可以达到相同的效果。
在JavaScript中,有时候我们需要迭代一个数组,并且以每一对(当前值,下一个值)的形式进行操作。下面的代码展示了如何实现这个功能:
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) })
上述代码中的函数`pairwise`接受一个数组和一个函数作为参数。它通过迭代数组中的每个元素,将当前元素和下一个元素作为参数传递给函数。通过这种方式,我们可以在函数中对每对元素进行操作。
然而,上述代码只能迭代相邻的一对元素。如果我们想要迭代所有相隔一定间隔的元素对,我们可以稍作修改:
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) // 显示 (1, 3), (2, 4), (3, 5) , (4, 6), (5, 7) }, 2)
在上述代码中,我们添加了一个可选的参数`skips`,用来指定迭代时的间隔。这样,我们就可以迭代所有相隔指定间隔的元素对。
文章中还提到了一个更好的第三个参数,即`windowLength`,用来调整滑动窗口的大小。这样,我们不仅可以进行简单的`pairwise`迭代,还可以进行滑动分组的操作,比如`[1, 2, 3]`和`[2, 3, 4]`。作者认为这个功能可以作为一个贡献给lodash的PR(Pull Request),并提供了一个可能的实现。
总结起来,通过将一部分代码封装成函数,我们可以实现以一对一对的方式迭代数组,并进行相应的操作。如果需要迭代不同间隔的元素对,我们可以通过修改函数的参数来实现。这种方法可以极大地简化代码,并提高可读性和灵活性。
在JavaScript中,当我们需要按照一对一对的方式迭代数组时,可能会遇到一些问题。下面是一个解决这个问题的方法,它使用了可迭代对象和生成器函数。
function* pairwise(iterable) { const iterator = iterable[Symbol.iterator](); let a = iterator.next(); if (a.done) return; let b = iterator.next(); while (!b.done) { yield [a.value, b.value]; a = b; b = iterator.next(); } } console.log("array (0):", ...pairwise([])); console.log("array (1):", ...pairwise(["apple"])); console.log("array (4):", ...pairwise(["apple", "orange", "kiwi", "banana"])); console.log("set (4):", ...pairwise(new Set(["apple", "orange", "kiwi", "banana"])));
该方法的优点如下:
- 可以适用于所有可迭代对象,而不仅仅是数组(例如Set)。
- 不会创建任何中间或临时数组。
- 惰性求值,可以高效地处理非常大的可迭代对象。
另外,还提供了TypeScript版本的实现,代码如下:
function* pairwise(iterable: Iterable ): Generator<[T, T], void> { const iterator = iterable[Symbol.iterator](); let a = iterator.next(); if (a.done) return; let b = iterator.next(); while (!b.done) { yield [a.value, b.value]; a = b; b = iterator.next(); } }
这个解决方案非常出色!但是,为了满足问题的要求,我会将循环改为`while (!next.done)`,以避免在最后一次迭代中第二个元素是`undefined`。