I have the array: [1,2,3,4,5,6,7]
I want to achieve: [[1,2], [3,4], [5,6], [7]]
I'm thinking Array.map, but it doesn't seem to be able to map to nothing for an element?
I have (using Underscorejs):
arr.map(function(el, idx, arr) {
if (idx%2 != 0) return null;
if (idx == arr.length-1) return [el];
return [el, arr[idx+1]]
}).compact();
This is still a bit ugly. How can I achieve the transformation (without explicit loop)?
A map key can hold the null value. Adding a map entry with a key that matches an existing key in the map overwrites the existing entry with that key with the new entry. Map keys of type String are case-sensitive. Two keys that differ only by the case are considered unique and have corresponding distinct Map entries.
Doing . map() on empty array will not produces an error, but will return an empty array. Which is fine because empty array is a renderable item in react and won't produce error in render() and will not render the notes as there are no notes provided. Save this answer.
Since map builds a new array, calling it without using the returned array is an anti-pattern; use forEach or for...of instead.
reduce
the array using the modulo operator:
function chunk(arr, n) {
return arr.reduce(function (p, c, i) {
if (i % n === 0) p.push([]);
p[p.length - 1].push(c);
return p;
}, []);
}
chunk(arr, 2); // [[1,2],[3,4],[5,6],[7]]
DEMO
The map
function can't do that, it's a structure-preserving transformation.
You could write this "chunking" as a reduce
, a plain loop, or something weird like
var arr = [1,2,3,4,5,6,7];
return arr.filter(function(_, i) {
return i%2==0;
}).map(function(x, i) {
return i*2+1<arr.length ? [x, arr[i*2+1]] : [x];
});
or
return arr.map(function(_, i) {
return arr.slice(i, 2);
}).filter(function(_, i) {
return i%2==0;
})
See also Split array into chunks for many more variants (some of them quite functional).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With