Split JavaScript array in chunks using Lodash
JavascriptSplitFunctional Programmingunderscore.jsLodashJavascript Problem Overview
I need to split a JavaScript array into n
sized chunks.
E.g.: Given this array
["a1", "a2", "a3", "a4", "a5", "a6", "a7", "a8", "a9", "a10", "a11", "a12", "a13"]
and a n
equals to 4, the output should be this:
[ ["a1", "a2", "a3", "a4"],
["a5", "a6", "a7", "a8"],
["a9", "a10", "a11", "a12"],
["a13"]
]
I aware of pure JavaScript solutions for this problem, but since I am already using Lodash I am wondering if Lodash provides a better solution for this.
Edit:
I created a jsPerf test to check how much slower the underscore solution is.
Javascript Solutions
Solution 1 - Javascript
Take a look at lodash' chunk: https://lodash.com/docs#chunk
const data = ["a1", "a2", "a3", "a4", "a5", "a6", "a7", "a8", "a9", "a10", "a11", "a12", "a13"];
const chunks = _.chunk(data, 3);
console.log(chunks);
// [// ["a1", "a2", "a3"],
// ["a4", "a5", "a6"],
// ["a7", "a8", "a9"],
// ["a10", "a11", "a12"],
// ["a13"]
// ]
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"></script>
Solution 2 - Javascript
For Underscore based solution try this:
var data = ["a1", "a2", "a3", "a4", "a5", "a6", "a7", "a8", "a9", "a10", "a11", "a12", "a13"];
var n = 3;
var lists = _.groupBy(data, function(element, index){
return Math.floor(index/n);
});
lists = _.toArray(lists); //Added this to convert the returned object to an array.
console.log(lists);
Using the chain wrapper method you can combine the two statements as below:
var data = ["a1", "a2", "a3", "a4", "a5", "a6", "a7", "a8", "a9", "a10", "a11", "a12", "a13"];
var n = 3;
var lists = _.chain(data).groupBy(function(element, index){
return Math.floor(index/n);
}).toArray()
.value();
Solution 3 - Javascript
A possibly simpler expression:
const coll = [ "a1", "a2", "a3", "a4", "a5", "a6", "a7", "a8", "a9" ];
const n = 2;
const chunks = _.range(coll.length / n).map(i => coll.slice(i * n, (i + 1) * n));
console.log(chunks);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"></script>
Solution 4 - Javascript
Underscore supports _.chunk() natively as of version 1.9.0.
const data = ["a1", "a2", "a3", "a4", "a5", "a6", "a7", "a8", "a9", "a10", "a11", "a12", "a13"];
const chunks = _.chunk(data, 4);
console.log(chunks);
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.9.1/underscore.js"></script>
Solution 5 - Javascript
try this one it is much more practical (for example, if you would want to split the array based on amount of items to be container in each sub array):
function chunk(arr, start, amount){
var result = [],
i,
start = start || 0,
amount = amount || 500,
len = arr.length;
do {
//console.log('appending ', start, '-', start + amount, 'of ', len, '.');
result.push(arr.slice(start, start+amount));
start += amount;
} while (start< len);
return result;
};
and the use in your case:
var arr = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17],
chunked = chunk(arr, 0, Math.floor(arr.length/3)); //to get 4 nested arrays
console.log(chunked);
and another case:
var arr = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17],
chunked = chunk(arr, 0, 3); // to get 6 nested arrays each containing maximum of 3 items
console.log(chunked);