让我们说我有一个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传播功能#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)));
其他回答
修改自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));
}});
这是一个带有尾递归和数组解构的版本。
远非最快的性能,但我只是觉得好笑,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]]
对源数组进行突变:
let a = [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ], aa = [], x
while((x = a.splice(0, 2)).length) aa.push(x)
// aa == [ [ 1, 2 ], [ 3, 4 ], [ 5, 6 ], [ 7, 8 ], [ 9 ] ]
// a == []
不改变源数组:
let a = [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ], aa = []
for(let i = 0; i < a.length; i += 2) aa.push(a.slice(i, i + 2))
// aa == [ [ 1, 2 ], [ 3, 4 ], [ 5, 6 ], [ 7, 8 ], [ 9 ] ]
// a == [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
为这个https://www.npmjs.com/package/array.chunk创建一个npm包
var result = [];
for (var i = 0; i < arr.length; i += size) {
result.push(arr.slice(i, size + i));
}
return result;
当使用TypedArray时
var result = [];
for (var i = 0; i < arr.length; i += size) {
result.push(arr.subarray(i, size + i));
}
return result;
现在你可以使用lodash的chunk函数将数组分割成更小的数组https://lodash.com/docs#chunk不再需要摆弄循环了!