让我们说我有一个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个元素?
当前回答
迟到了,这是我的意见。就像很多人说的,我首先会想到的是
chunker = (a,n) => [...Array(Math.ceil(a.length/n))].map((v,i) => a.slice(i*n, (i+1)*n))
但我更喜欢但还没看到的是:
chunker = (n) => (r,v,i) => (c = Math.floor(i/n), (r[c] = r[c] || []).push(v), r)
console.log(arr.reduce(chunker(3), []))
有更长的变体
chunker = (a, n) => a.reduce((r,v,i) => {
c = Math.floor(i/n); // which chunk it belongs to
(r[c] = r[c] || []).push(v)
return r
}, [])
console.log(chunker(arr, 3))
解释
常见的答案将首先确定块的数量,然后根据块所在的位置和每个块的大小获得原始数组的切片 块减速器函数将遍历每个元素,并将其放入相应评估的块数组中。
性能几乎相同,据我所见,reduce方法平均慢了4%。
PS: reduce(ing)的优点是很容易改变分组标准。在问题和例子中,标准是相邻的单元格(映射使用切片)。但是你可能想要在“循环”中做它,例如,使用mod (% operator),或任何其他数学公式
重新阅读它让我发现这个公式也可以是一个参数,导致一个更通用的解决方案,需要2个函数来实现答案:
splitter = (a, f) => a.reduce((r,v,i) => { // math formula and/or function
c = f(v, i) || 0; // custom formula, receiving each value and index
(r[c] = r[c] || []).push(v)
return r
}, [])
chunker = (a, n) => splitter(a, (v,i) => Math.floor(i/n))
console.log(chunker(arr, 3))
console.log(splitter(arr, (v,i) => v % 2)) // is it even or odd?
splitter也可以用于创建命名数组,也就是对象,函数返回字符串而不是数字:)
其他回答
纯javascript中的一行代码:
函数块(数组,大小){ 返回数组中。应用(0,{长度:Math.ceil(数组。长度/大小)})。Map ((_, index) =>数组。片(指数*大小,大小(指数+ 1)*)) } //下面将字母表中的字母按4进行分组 console.log(块(数组(26)[…]. map ((x, i) = > String.fromCharCode (+ 97), 4))
我的目标是在纯ES6中创建一个简单的非突变解决方案。javascript的特性使得在映射之前必须填充空数组:-(
function chunk(a, l) {
return new Array(Math.ceil(a.length / l)).fill(0)
.map((_, n) => a.slice(n*l, n*l + l));
}
这个带有递归的版本似乎更简单,也更引人注目:
function chunk(a, l) {
if (a.length == 0) return [];
else return [a.slice(0, l)].concat(chunk(a.slice(l), l));
}
ES6中荒谬的弱数组函数可以制作出很好的谜题:-)
编辑:@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的值可以改变较小数组的最大长度。
整洁干净,易于理解
let nums = [1, 2, 3, 4, 5, 6, 7, 8, 9];
let len = nums.length ;
const chunkArr = (arr, chunkNo) => {
let newArr = [];
for(let i = 0; i < len; i++){
if(nums[0] !== "" && nums[0] !== undefined ){
let a = nums.splice(0,chunkNo) ;
newArr.push(a);
}
}
return newArr ;
}
console.log(chunkArr(nums, 5));
# 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 ' '