让我们说我有一个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个元素?
当前回答
一行程序
const chunk = (a,n)=>[...Array(Math.ceil(a.length/n))].map((_,i)=>a.slice(n*i,n+n*i));
为打印稿
const chunk = <T>(arr: T[], size: number): T[][] =>
[...Array(Math.ceil(arr.length / size))].map((_, i) =>
arr.slice(size * i, size + size * i)
);
DEMO
const块= (n) = >[…]数组(Math.ceil (a.length / n))) . map ((_, i) = > a.slice (n * n + n * i)); document . write (JSON。Stringify (chunk([1,2,3,4], 2)));
按组数分组
const part=(a,n)=>[...Array(n)].map((_,i)=>a.slice(i*Math.ceil(a.length/n),(i+1)*Math.ceil(a.length/n)));
为打印稿
const part = <T>(a: T[], n: number): T[][] => {
const b = Math.ceil(a.length / n);
return [...Array(n)].map((_, i) => a.slice(i * b, (i + 1) * b));
};
DEMO
Const部分= (a, n) => { const b = Math.ceil(a。长度/ n); 返回数组(n)[…]。Map ((_, i) => .slice(i * b, (i + 1) * b)); }; document . write (JSON。Stringify (part([1,2,3,4,5,6], 2))+'<br/>'); document . write (JSON。Stringify (part([1,2,3,4,5,6,7], 2)));
其他回答
下面的ES2015方法不需要定义函数,直接在匿名数组上工作(例如块大小为2):
[11,22,33,44,55].map((_, i, all) => all.slice(2*i, 2*i+2)).filter(x=>x.length)
如果你想为此定义一个函数,你可以这样做(改进K._对Blazemonger的回答的评论):
const array_chunks = (array, chunk_size) => array
.map((_, i, all) => all.slice(i*chunk_size, (i+1)*chunk_size))
.filter(x => x.length)
为这个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;
这就是我对这个话题的贡献。我想.reduce()是最好的方法。
Var segment = (arr, n) => arr.reduce((r,e,i) => i%n ?(r [r.length-1] .push (e), r) (r.push([e]), r), []), arr = Array.from({length: 31}).map((_,i) => i+1); Res = segment(arr,7); console.log (JSON.stringify (res));
但是上面的实现不是很有效,因为.reduce()运行在所有arr函数中。一个更有效的方法(非常接近最快的强制解决方案)是,迭代缩减(要分块)数组,因为我们可以通过Math.ceil(arr/n);提前计算它的大小。一旦我们有一个空的结果数组,比如array (Math.ceil(arr.length/n)).fill();剩下的是将arr数组的切片映射到它。
功能块(加勒比海盗,n) { var r = Array(Math.ceil(arr.length/n)).fill(); 返回r.map((e,i) => arr。片(我* n * n + n)); } arr = Array.from({length: 31},(_,i) => i+1); Res = chunk(arr,7); console.log (JSON.stringify (res));
到目前为止还不错,但我们仍然可以进一步简化上面的片段。
var chunk = (a,n) => Array.from({length: Math.ceil(a.length/n)}, (_,i) => a.slice(i*n, i*n+n)), arr = Array.from({length: 31},(_,i) => i+1), res = chunk(arr,7); console.log(JSON.stringify(res));
下面是使用reduce()方法的另一个解决方案,尽管与其他示例略有不同。希望我的解释也能更清楚一点。
Var arr = [0,1,2,3,4,5,6,7]; var chunkSize = 3; Arr = Arr。Reduce ((acc, item, idx) => { Let group = acc.pop(); 如果(集团。长度== chunkSize) { acc.push(集团); Group = []; } group.push(项); acc.push(集团); 返回acc; }, [[]]); console.log (arr);//打印[[0,1,2],[3,4,5],[6,7]]
解释
我们称之为reducer,它对数组中的每一项都使用pop()获取累加器的最后一项。记住,这个项是一个数组,它将最多为chunkSize数量的项进行分组(在本例中为3)。
当且仅当该组的数组长度等于chunksize时,我们需要将该组重新插入到累加器中并创建一个新组。
然后将当前项推入我们的组数组(它可能已经包含前面步骤中的0、1或2个项)。将当前项插入组后,我们需要将组重新插入到更大的集合中。
该过程将重复进行,直到遍历arr中的所有项。
注意,我们还使用[[]]为减速器提供了数组中空数组的起始值。
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将导致无限循环。