Split array into chunks

2018-12-31 00:08发布

Let's say that I have an Javascript array looking as following:

["Element 1","Element 2","Element 3",...]; // with close to a hundred elements.

What approach would be appropriate to chunk (split) the array into many smaller arrays with, lets say, 10 elements at its most?

30条回答
梦醉为红颜
2楼-- · 2018-12-31 00:49

EDIT: @mblase75 added more concise code to the earlier answer while I was writing mine, so I recommend going with his solution.

You could use code like this:

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));
}

Change the value of arraySize to change the maximum length of the smaller arrays.

查看更多
萌妹纸的霸气范
3楼-- · 2018-12-31 00:50

Ok, let's start with a fairly tight one:

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); });
}

Which is used like this:

chunk([1,2,3,4,5,6,7], 2);

Then we have this tight reducer function:

function chunker(p, c, i) {
    (p[i/this|0] = p[i/this|0] || []).push(c);
    return p;
}

Which is used like this:

[1,2,3,4,5,6,7].reduce(chunker.bind(3),[]);

Since a kitten dies when we bind this to a number, we can do manual currying like this instead:

// 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;
   };
}

Which is used like this:

[1,2,3,4,5,6,7].reduce(chunker(3),[]);

Then the still pretty tight function which does it all in one go:

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);
查看更多
泛滥B
4楼-- · 2018-12-31 00:50

I just wrote this with the help of a groupBy function.

// utils
const group = (source) => ({
  by: (grouping) => {
    const groups = source.reduce((accumulator, item) => {
      const name = JSON.stringify(grouping(item));
      accumulator[name] = accumulator[name] || [];
      accumulator[name].push(item);
      return accumulator;
    }, {});

    return Object.keys(groups).map(key => groups[key]);
  }
});

const chunk = (source, size) => group(source.map((item, index) => ({ item, index })))
.by(x => Math.floor(x.index / size))
.map(x => x.map(v => v.item));


// 103 items
const arr = [6,2,6,6,0,7,4,9,3,1,9,6,1,2,7,8,3,3,4,6,8,7,6,9,3,6,3,5,0,9,3,7,0,4,1,9,7,5,7,4,3,4,8,9,0,5,1,0,0,8,0,5,8,3,2,5,6,9,0,0,1,5,1,7,0,6,1,6,8,4,9,8,9,1,6,5,4,9,1,6,6,1,8,3,5,5,7,0,8,3,1,7,1,1,7,6,4,9,7,0,5,1,0];

const chunks = chunk(arr, 10);

console.log(JSON.stringify(chunks));

查看更多
残风、尘缘若梦
5楼-- · 2018-12-31 00:51

Here's my approach using Coffeescript list comprehension. A great article detailing comprehensions in Coffeescript can be found here.

chunk: (arr, size) ->
    chunks = (arr.slice(index, index+size) for item, index in arr by size)
    return chunks
查看更多
公子世无双
6楼-- · 2018-12-31 00:54

ES6 one-line approach based on Array.prototype reduce and push methods:

const doChunk = (list, size) => list.reduce((r, v) =>
  (!r.length || r[r.length - 1].length === size ?
    r.push([v]) : r[r.length - 1].push(v)) && r
, []);

console.log(doChunk([0,1,2,3,4,5,6,7,8,9,10,11,12], 5));
// [[0, 1, 2, 3, 4], [5, 6, 7, 8, 9], [10, 11, 12]]
查看更多
浮光初槿花落
7楼-- · 2018-12-31 00:54

I changed BlazeMonger's slightly to use for a jQuery object..

var $list = $('li'),
    $listRows = [];


for (var i = 0, len = $list.length, chunk = 4, n = 0; i < len; i += chunk, n++) {
   $listRows[n] = $list.slice(i, i + chunk);
}
查看更多
登录 后发表回答