Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Array.map want to map a value to nothing

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)?

like image 769
Boyang Avatar asked Mar 16 '16 12:03

Boyang


People also ask

Can a map return null?

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.

Can you map over empty array?

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.

Can I use map without return?

Since map builds a new array, calling it without using the returned array is an anti-pattern; use forEach or for...of instead.


2 Answers

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

like image 127
Andy Avatar answered Sep 22 '22 07:09

Andy


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).

like image 30
Bergi Avatar answered Sep 20 '22 07:09

Bergi