让我们说我有一个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个元素?
当前回答
修改自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));
}});
其他回答
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将导致无限循环。
这是一个带有尾递归和数组解构的版本。
远非最快的性能,但我只是觉得好笑,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]]
我试过递归函数…
const chunk = (arr, n) =>
arr.length ? [arr.slice(0, n), ...chunk(arr.slice(n), n)] : [];
……这很好,很短,但似乎是@AymKdn回答1000个元素用时的256倍,10000个元素用时的1058倍!
编辑:@mblase75在我写我的答案时在前面的答案上添加了更简洁的代码,所以我建议使用他的解决方案。
你可以使用这样的代码:
var longArray = ["Element 1","Element 2","Element 3", /*...*/];
var smallerArrays = []; // will contain the sub-arrays of 10 elements each
var arraySize = 10;
for (var i=0;i<Math.ceil(longArray.length/arraySize);i++) {
smallerArrays.push(longArray.slice(i*arraySize,i*arraySize+arraySize));
}
修改arraySize的值可以改变较小数组的最大长度。
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);