首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在JavaScript中将数组作为对(current,next)进行迭代

在JavaScript中将数组作为对(current,next)进行迭代
EN

Stack Overflow用户
提问于 2015-08-13 02:55:25
回答 11查看 20.4K关注 0票数 26

在问题Iterate a list as pair (current, next) in Python中,OP感兴趣的是将Python列表作为一系列current, next对进行迭代。我也有同样的问题,但是我想用最干净的方式在JavaScript中解决这个问题,也许可以使用lodash

使用一个简单的for循环很容易做到这一点,但感觉并不是很优雅。

代码语言:javascript
运行
复制
for (var i = 0; i < arr.length - 1; i++) {
  var currentElement = arr[i];
  var nextElement = arr[i + 1];
}

Lodash几乎可以做到这一点:

代码语言:javascript
运行
复制
_.forEach(_.zip(arr, _.rest(arr)), function(tuple) {
  var currentElement = tuple[0];
  var nextElement = tuple[1];
})

在最后一次迭代中,nextElement将是undefined,这是一个微妙的问题。

当然,理想的解决方案应该是一个只在必要时循环的pairwise lodash函数。

代码语言:javascript
运行
复制
_.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中询问的内容。

EN

Stack Overflow用户

发布于 2018-02-21 19:02:54

下面是一个没有任何依赖项的通用函数解决方案:

代码语言:javascript
运行
复制
const nWise = (n, array) => {
  iterators = Array(n).fill()
    .map(() => array[Symbol.iterator]());
  iterators
    .forEach((it, index) => Array(index).fill()
      .forEach(() => it.next()));
  return Array(array.length - n + 1).fill()
    .map(() => (iterators
      .map(it => it.next().value);
};

const pairWise = (array) => nWise(2, array);

我知道看起来一点都不好,但通过引入一些通用的实用函数,我们可以让它看起来更好:

代码语言:javascript
运行
复制
const sizedArray = (n) => Array(n).fill();

我可以结合使用sizedArrayforEach来实现times,但这是一个低效的实现。对于这样一个不言自明的函数,使用命令式代码是可以的:

代码语言:javascript
运行
复制
const times = (n, cb) => {
  while (0 < n--) {
    cb();
  }
}

如果您对更多核心解决方案感兴趣,请查看this answer。

不幸的是,Array.fill只接受单个值,不接受回调。所以Array(n).fill(array[Symbol.iterator]())会在每个位置放置相同的值。我们可以通过以下方式来解决这个问题:

代码语言:javascript
运行
复制
const fillWithCb = (n, cb) => sizedArray(n).map(cb);

最终实现:

代码语言:javascript
运行
复制
const nWise = (n, array) => {
  iterators = fillWithCb(n, () => array[Symbol.iterator]());
  iterators.forEach((it, index) => times(index, () => it.next()));
  return fillWithCb(
    array.length - n + 1,
    () => (iterators.map(it => it.next().value),
  );
};

通过将参数样式更改为currying,配对的定义看起来会好得多:

代码语言:javascript
运行
复制
const nWise = n => array => {
  iterators = fillWithCb(n, () => array[Symbol.iterator]());
  iterators.forEach((it, index) => times(index, () => it.next()));
  return fillWithCb(
    array.length - n + 1,
    () => iterators.map(it => it.next().value),
  );
};

const pairWise = nWise(2);

如果你运行下面的代码,你会得到:

代码语言:javascript
运行
复制
> pairWise([1, 2, 3, 4, 5]);
// [ [ 1, 2 ], [ 2, 3 ], [ 3, 4 ], [ 4, 5 ] ]
票数 3
EN
查看全部 11 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31973278

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档