让我们说我有一个Javascript数组看起来如下:
["Element 1","Element 2","Element 3",...]; // with close to a hundred elements.
什么样的方法适合将数组分成许多更小的数组,假设最多有10个元素?
让我们说我有一个Javascript数组看起来如下:
["Element 1","Element 2","Element 3",...]; // with close to a hundred elements.
什么样的方法适合将数组分成许多更小的数组,假设最多有10个元素?
当前回答
如果你使用EcmaScript >= 5.1版本,你可以使用array.reduce()实现一个函数版本的chunk(),复杂度为O(N):
function chunk(chunkSize, array) { return array.reduce(function(previous, current) { var chunk; if (previous.length === 0 || previous[previous.length -1].length === chunkSize) { chunk = []; // 1 previous.push(chunk); // 2 } else { chunk = previous[previous.length -1]; // 3 } chunk.push(current); // 4 return previous; // 5 }, []); // 6 } console.log(chunk(2, ['a', 'b', 'c', 'd', 'e'])); // prints [ [ 'a', 'b' ], [ 'c', 'd' ], [ 'e' ] ]
以上每个// nbr的解释:
如果之前的值,即之前返回的块数组是空的,或者如果之前的最后一个块有chunkSize项,则创建一个新的块 将新数据块添加到现有数据块数组中 否则,当前块是块数组中的最后一个块 将当前值添加到块中 返回修改后的块数组 通过传递一个空数组初始化还原
基于chunkSize的curry:
var chunk3 = function(array) {
return chunk(3, array);
};
console.log(chunk3(['a', 'b', 'c', 'd', 'e']));
// prints [ [ 'a', 'b', 'c' ], [ 'd', 'e' ] ]
你可以将chunk()函数添加到全局Array对象:
Object.defineProperty(Array.prototype, 'chunk', { value: function(chunkSize) { return this.reduce(function(previous, current) { var chunk; if (previous.length === 0 || previous[previous.length -1].length === chunkSize) { chunk = []; previous.push(chunk); } else { chunk = previous[previous.length -1]; } chunk.push(current); return previous; }, []); } }); console.log(['a', 'b', 'c', 'd', 'e'].chunk(4)); // prints [ [ 'a', 'b', 'c' 'd' ], [ 'e' ] ]
其他回答
ES6传播功能#ohmy #ftw
Const chunk = (size, xs) => xs.reduce ( (segments, _, index) => 索引%大小=== 0 ? […段,x。Slice (index, index + size)] 段, [] ); console.log(块(3,(1,2,3,4,5,6,7,8)));
array.slice()方法可以根据需要从数组的开头、中间或结尾提取切片,而不需要改变原始数组。
const chunkSize = 10;
for (let i = 0; i < array.length; i += chunkSize) {
const chunk = array.slice(i, i + chunkSize);
// do whatever
}
最后一个块可能小于chunkSize。例如,当给定一个包含12个元素的数组时,第一个块将有10个元素,第二个块只有2个。
注意,chunkSize为0将导致无限循环。
对于功能性的解决方案,使用Ramda:
其中,popularProducts是输入数组,5是数据块大小
导入splitEvery from 'ramda/src/splitEvery' popularProducts splitEvery(5)。Map ((chunk, i) => { //用chunk做一些事情 })
下面是使用reduce()方法的另一个解决方案,尽管与其他示例略有不同。希望我的解释也能更清楚一点。
Var arr = [0,1,2,3,4,5,6,7]; var chunkSize = 3; Arr = Arr。Reduce ((acc, item, idx) => { Let group = acc.pop(); 如果(集团。长度== chunkSize) { acc.push(集团); Group = []; } group.push(项); acc.push(集团); 返回acc; }, [[]]); console.log (arr);//打印[[0,1,2],[3,4,5],[6,7]]
解释
我们称之为reducer,它对数组中的每一项都使用pop()获取累加器的最后一项。记住,这个项是一个数组,它将最多为chunkSize数量的项进行分组(在本例中为3)。
当且仅当该组的数组长度等于chunksize时,我们需要将该组重新插入到累加器中并创建一个新组。
然后将当前项推入我们的组数组(它可能已经包含前面步骤中的0、1或2个项)。将当前项插入组后,我们需要将组重新插入到更大的集合中。
该过程将重复进行,直到遍历arr中的所有项。
注意,我们还使用[[]]为减速器提供了数组中空数组的起始值。
我试过递归函数…
const chunk = (arr, n) =>
arr.length ? [arr.slice(0, n), ...chunk(arr.slice(n), n)] : [];
……这很好,很短,但似乎是@AymKdn回答1000个元素用时的256倍,10000个元素用时的1058倍!