ES5/6/下一种在JavaScript中通过数组进行分组或块迭代的方法

ES5/6/下一种在JavaScript中通过数组进行分组或块迭代的方法,javascript,ecmascript-6,ecmascript-5,ecmascript-next,Javascript,Ecmascript 6,Ecmascript 5,Ecmascript Next,假设我有一个数组,我想一次迭代N个数组。我可以使用一个简单的嵌套循环 const array = ['a','b','c','d','e','f','g','h']; const step = 3; for (let i = 0; i < array.length; i += step) { const end = Math.min(i + step, array.length); console.log("page:", i / step); for (let j =

假设我有一个数组,我想一次迭代N个数组。我可以使用一个简单的嵌套循环

const array = ['a','b','c','d','e','f','g','h'];
const step = 3;
for (let i = 0; i < array.length; i += step) {
   const end = Math.min(i + step, array.length);
   console.log("page:", i / step);
   for (let j = i; j < end; ++j) {
     const element = array[j];
     console.log("  ", element);
   }
}
但我想知道现在JavaScript中是否有一种更现代的方式,类似于forEach的方式。想象一下:

// pseudo code
const chunkSize = 3
forEachByChunk(array, chunkSize, (subArray, chunkNdx, startingNdxInParentArray) => {
  console.log("page:", chunkNdx);
  subArray.forEach((element) => { console.log("  ", element); });
});
注意:我可以编写自己的
forEachByChunk

function forEachByChunk(array, chunkSize, fn) {
  const end = array.length;
  for (let i = 0; i < end; i += chunkSize) {
    fn(array.slice(i, i + chunkSize), i / chunkSize, i);
  }
}
函数forEachByChunk(数组,chunkSize,fn){
const end=array.length;
for(设i=0;i

我只是想知道是否已经有一些内置的现代方式在JavaScript中实现这一点。或者更通用的版本。

使用切片和贴图可以解决问题

const step=3;
常量数组=['a'、'b'、'c'、'd'、'e'、'f'、'g'、'h'];
var pages=array.map((字母,索引)=>index%step==0?array.slice(索引,索引+步骤):[])
.filter((页面)=>页面长度>=0)
我只是想知道是否已经有一些内置的现代方式在JavaScript中实现这一点

不,没有

或者更通用的版本

有许多用户版本。谷歌搜索“javascript分区数组”。开始吧。

从lodash退房。这正是你想要的

查看lodash和rambda。他们几乎有任何你能想到的通用助手方法

\ chunk([1,2,3,4,5,6,7,8],3)
返回
[[1,2,3],[4,5,6],[7,8]

编辑: 如果您正在寻找如何使用一些新语法来实现这样的事情,那么这就是您可以做到的

const chunk = size => list =>
  list
    .map((value, index) => ({ value, step: index % size }))
    .reduce(
      (accum, item) => {
        const { value, step } = item;
        if (step === 0) return [[value], ...accum];
        const [head, ...tail] = accum;
        return [[...head, value], ...tail];
      },
      [],
    ).slice().reverse();

我希望你不要用这个。这没有经过测试,使用lodash可能会更好。

不,几乎所有内置程序都会在不跳过索引的情况下迭代整个数组。您可以在回调中使用一个条件,但是像第一个示例中那样,只使用
for
循环更有效。添加到本机原型通常不是一个很好的主意,因为我实现了array.stride正是出于这个原因。在npm上搜索它。由于这是自我推销,除非有人要求,否则我不会把它作为一个答案。另外,我一直希望为ES8提出array.stride,但还没有时间来写proposal@slebetman没有充分的理由使用本机块迭代器,原因有二。首先,很容易从元素迭代器构建块迭代器。其次,它没有提供任何性能优势,因为您必须迭代块中的每个元素来复制整个块。例如,如果您使用
slice
创建块,那么您正在迭代块的每个元素以复制它。@AaditMShah:代码清晰总是有很好的理由的。就像函数的
.bind()
方法一样。通过您的推理,没有充分的理由在语言中使用它,因为您可以实现它。对于块迭代器,您可以通过在cb中实现它来提高性能,但OP似乎在寻找内置的块迭代器。或者更通用的版本。这两者都不是。splice和map是内置的泛型方法,我不明白2个向下的投票支持这个,2个向上的投票支持一个答案说不,没有问题是,“是否有内置的分区方法”。正确答案是“不,没有”。如果OP是在寻找一种自己开发的用户编写的分区算法,那么通过简单的搜索就可以找到数百种明显优于您的算法。OP是在寻找一种内置的区块迭代器。因此,使用lodash是一个大禁忌。
const chunk = size => list =>
  list
    .map((value, index) => ({ value, step: index % size }))
    .reduce(
      (accum, item) => {
        const { value, step } = item;
        if (step === 0) return [[value], ...accum];
        const [head, ...tail] = accum;
        return [[...head, value], ...tail];
      },
      [],
    ).slice().reverse();