让我们说我有一个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个元素?
当前回答
好吧,让我们从一个相当严格的开始:
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);
其他回答
这个问题可能有很多解决方案。
我最喜欢的一个是:
function chunk(array, size) { const chunked = []; for (element of array){ let last = chunked[chunked.length - 1]; if(last && last.length != size){ last.push(element) }else{ chunked.push([element]) } } return chunked; } function chunk1(array, size) { const chunked = []; let index = 0; while(index < array.length){ chunked.push(array.slice(index,index+ size)) index += size; } return chunked; } console.log('chunk without slice:',chunk([1,2,3,4,5,5],2)); console.log('chunk with use of slice funtion',chunk1([1,2,3,4,5,6],2))
我在jsperf.com上测试了不同的答案。结果可以在https://web.archive.org/web/20150909134228/https://jsperf.com/chunk-mtds上找到
最快的函数(从IE8开始运行)是这个:
function chunk(arr, chunkSize) {
if (chunkSize <= 0) throw "Invalid chunk size";
var R = [];
for (var i=0,len=arr.length; i<len; i+=chunkSize)
R.push(arr.slice(i,i+chunkSize));
return R;
}
这里是一个仅使用递归和slice()的非突变解决方案。
const splitToChunks = (arr, chunkSize, acc = []) => (
arr.length > chunkSize ?
splitToChunks(
arr.slice(chunkSize),
chunkSize,
[...acc, arr.slice(0, chunkSize)]
) :
[...acc, arr]
);
然后简单地像splitToChunks([1,2,3,4,5], 3)一样使用它来获得[[1,2,3],[4,5]]。
这里有一个小提琴供你尝试:https://jsfiddle.net/6wtrbx6k/2/
我更喜欢使用拼接法而不是切片法。 这个解决方案使用数组长度和块大小来创建循环计数,然后循环遍历数组,在每个步骤中由于拼接而在每个操作后变得更小。
function chunk(array, size) {
let resultArray = [];
let chunkSize = array.length/size;
for(i=0; i<chunkSize; i++) {
resultArray.push(array.splice(0, size));
}
return console.log(resultArray);
}
chunk([1,2,3,4,5,6,7,8], 2);
如果不想改变原始数组,可以使用展开操作符克隆原始数组,然后使用该数组来解决问题。
let clonedArray = [...OriginalArray]
# in coffeescript
# assume "ar" is the original array
# newAr is the new array of arrays
newAr = []
chunk = 10
for i in [0... ar.length] by chunk
newAr.push ar[i... i+chunk]
# or, print out the elements one line per chunk
for i in [0... ar.length] by chunk
console.log ar[i... i+chunk].join ' '