让我们说我有一个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个元素?
当前回答
ES6 Generator版本
function* chunkArray(array,size=1){
var clone = array.slice(0);
while (clone.length>0)
yield clone.splice(0,size);
};
var a = new Array(100).fill().map((x,index)=>index);
for(const c of chunkArray(a,10))
console.log(c);
其他回答
这是一个带有尾递归和数组解构的版本。
远非最快的性能,但我只是觉得好笑,js现在可以做到这一点。即使它没有为此进行优化:(
const getChunks = (arr, chunk_size, acc = []) => {
if (arr.length === 0) { return acc }
const [hd, tl] = [ arr.slice(0, chunk_size), arr.slice(chunk_size) ]
return getChunks(tl, chunk_size, acc.concat([hd]))
}
// USAGE
const my_arr = [1,2,3,4,5,6,7,8,9]
const chunks = getChunks(my_arr, 2)
console.log(chunks) // [[1,2],[3,4], [5,6], [7,8], [9]]
这应该是一个简单的答案,没有太多的数学复杂性。
function chunkArray(array, sizeOfTheChunkedArray) {
const chunked = [];
for (let element of array) {
const last = chunked[chunked.length - 1];
if(!last || last.length === sizeOfTheChunkedArray) {
chunked.push([element])
} else {
last.push(element);
}
}
return chunked;
}
修改自dbaseman的回答:https://stackoverflow.com/a/10456344/711085
Object.defineProperty(Array.prototype, ' chunk_efficient ', { 值:function(chunkSize) { Var数组= this; 返回[].concat.apply ([], 数组中。映射(函数(elem, i) { 返回i % chunkSize ?[]: [array.]slice(i, i + chunkSize)]; }) ); } }); console.log ( [1,2,3,4,5,6,7]. chunk_efficient (3) ) // [[1,2,3], [4,5,6], [7]]
小齿顶:
我应该指出,上面的方法(在我看来)并不是使用Array.map的一种优雅的变通方法。它基本上做以下事情,其中~是连接:
[[1,2,3]]~[]~[]~[] ~ [[4,5,6]]~[]~[]~[] ~ [[7]]
它与下面的方法具有相同的渐近运行时间,但由于构建空列表,可能是一个更糟糕的常数因子。可以重写如下(与Blazemonger的方法大致相同,这就是我最初没有提交这个答案的原因):
更有效的方法:
如果你已经定义了Array.prototype.chunk,则刷新页面 Object.defineProperty(Array.prototype, 'chunk', { 值:function(chunkSize) { var R = []; For (var I = 0;I < this.length;i += chunkSize) R.push(这一点。slice(i, i + chunkSize)); 返回R; } }); console.log ( [1, 2, 3, 4, 5, 6, 7].chunk(3) )
我现在喜欢的方式是上面的,或者是下面的一种:
Array.range = function(n) {
// Array.range(5) --> [0,1,2,3,4]
return Array.apply(null,Array(n)).map((x,i) => i)
};
Object.defineProperty(Array.prototype, 'chunk', {
value: function(n) {
// ACTUAL CODE FOR CHUNKING ARRAY:
return Array.range(Math.ceil(this.length/n)).map((x,i) => this.slice(i*n,i*n+n));
}
});
演示:
> JSON.stringify( Array.range(10).chunk(3) );
[[1,2,3],[4,5,6],[7,8,9],[10]]
或者如果你不想要数组。Range函数,它实际上只是一行代码(不包括有绒毛的部分):
var ceil = Math.ceil;
Object.defineProperty(Array.prototype, 'chunk', {value: function(n) {
return Array(ceil(this.length/n)).fill().map((_,i) => this.slice(i*n,i*n+n));
}});
or
Object.defineProperty(Array.prototype, 'chunk', {value: function(n) {
return Array.from(Array(ceil(this.length/n)), (_,i)=>this.slice(i*n,i*n+n));
}});
好吧,让我们从一个相当严格的开始:
function chunk(arr, n) {
return arr.slice(0,(arr.length+n-1)/n|0).
map(function(c,i) { return arr.slice(n*i,n*i+n); });
}
它是这样使用的:
chunk([1,2,3,4,5,6,7], 2);
然后我们就有了这个紧密的减速器函数:
function chunker(p, c, i) {
(p[i/this|0] = p[i/this|0] || []).push(c);
return p;
}
它是这样使用的:
[1,2,3,4,5,6,7].reduce(chunker.bind(3),[]);
因为当我们将它绑定到一个数字时,小猫就死了,我们可以像这样手动curry:
// Fluent alternative API without prototype hacks.
function chunker(n) {
return function(p, c, i) {
(p[i/n|0] = p[i/n|0] || []).push(c);
return p;
};
}
它是这样使用的:
[1,2,3,4,5,6,7].reduce(chunker(3),[]);
然后是仍然非常紧凑的函数,它可以一次性完成所有操作:
function chunk(arr, n) {
return arr.reduce(function(p, cur, i) {
(p[i/n|0] = p[i/n|0] || []).push(cur);
return p;
},[]);
}
chunk([1,2,3,4,5,6,7], 3);
我只是在groupBy函数的帮助下写了这个。
// utils const group = (source) => ({ by: (grouping) => { const groups = source.reduce((accumulator, item) => { const name = JSON.stringify(grouping(item)); accumulator[name] = accumulator[name] || []; accumulator[name].push(item); return accumulator; }, {}); return Object.keys(groups).map(key => groups[key]); } }); const chunk = (source, size) => group(source.map((item, index) => ({ item, index }))) .by(x => Math.floor(x.index / size)) .map(x => x.map(v => v.item)); // 103 items const arr = [6,2,6,6,0,7,4,9,3,1,9,6,1,2,7,8,3,3,4,6,8,7,6,9,3,6,3,5,0,9,3,7,0,4,1,9,7,5,7,4,3,4,8,9,0,5,1,0,0,8,0,5,8,3,2,5,6,9,0,0,1,5,1,7,0,6,1,6,8,4,9,8,9,1,6,5,4,9,1,6,6,1,8,3,5,5,7,0,8,3,1,7,1,1,7,6,4,9,7,0,5,1,0]; const chunks = chunk(arr, 10); console.log(JSON.stringify(chunks));