Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Array.map 1 element to multiple element

I have [3, 16, 120]. when I do [3, 16, 120].map(mapper), I want to achieve, for example [4,5, 17,18, 121,122] i.e. each element map to n+1 and n+2. This is of course an example - what I want is to simply push multiple values from mapper function

Do I have to use Array.each and push to an array, or is it possible to do it with Array.map (or other built-in api)

like image 230
Boyang Avatar asked Jul 22 '16 14:07

Boyang


People also ask

Can you map two things at once JavaScript?

Summary. JavaScript doesn't support functions that return multiple values. However, you can wrap multiple values into an array or an object and return the array or the object.

How do I map multiple arrays?

To map multiple arrays with JavaScript, we can use the map method. to define the zip function that calls a1. map to combine the entries from a1 and a2 with index i into one entry. Then we call zip with arr1 and arr2 to zip them into one array.

Does map mutate array?

map does not mutate the array on which it is called (although callbackFn , if invoked, may do so). The range of elements processed by map is set before the first invocation of callbackFn .


10 Answers

You can use reduce() and add to array e+1, e+2 of each element.

var ar = [3, 16, 120];

var result = ar.reduce(function(r, e) {
  r.push(e+1, e+2);
  return r;
}, []);

console.log(result)

This is ES6 version with arrow function

var ar = [3, 16, 120];

var result = ar.reduce((r, e) => r.push(e+1, e+2) && r, []);
console.log(result)

PS: Array.push seems to be faster and has no Maximum call stack.. error, see below:

a = Array(1000000).fill(1); st = Date.now(); Array.prototype.concat.apply([], a.map(function (n) { return [n+1, n+2]; })); console.log(`${Date.now() - st}ms `);
> RangeError: Maximum call stack size exceeded

a = Array(1000000).fill(1); st = Date.now(); a.reduce((r, e) => r.push(e+1, e+2) && r, []); console.log(`${Date.now() - st}ms `);
> 180ms

So .push is preferable comparing to accepted solution.

like image 115
Nenad Vracar Avatar answered Sep 30 '22 06:09

Nenad Vracar


I come up with one myself, using spread operator.

[].concat(...[3, 16, 120].map(x => [x+1, x+2]))

like image 28
Boyang Avatar answered Sep 28 '22 06:09

Boyang


2019 Update

Use Array.prototype.flatMap(), introduced in ES10.

const oddNumbers = [1, 3, 5, 7, 9];
const allNumbers = oddNumbers.flatMap((number) => [number, number + 1]);
console.log(allNumbers); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
like image 33
jabacchetta Avatar answered Sep 26 '22 06:09

jabacchetta


Not particularly nice, but it is a possible solution:

var arr = [3, 16, 120];

console.log([].concat.apply([], arr.map(function (n) { return [n+1, n+2]; })));
like image 30
melpomene Avatar answered Sep 30 '22 06:09

melpomene


you could produce an array for each items, then concat all these arrays :

[3, 16, 120].map(x => [x+1, x+2] ).reduce( (acc,val) => acc.concat(val), []);
like image 41
Olivier Boissé Avatar answered Sep 29 '22 06:09

Olivier Boissé


You could use Array#reduce in combination with Array#concat.

console.log([3, 16, 120].reduce(function (r, a) {
    return r.concat(a + 1, a + 2);
}, []));

ES6

console.log([3, 16, 120].reduce((r, a) => r.concat(a + 1, a + 2), []));
like image 36
Nina Scholz Avatar answered Sep 28 '22 06:09

Nina Scholz


Immutable solution, with the spread operator:

[3, 16, 120].reduce((a, v) => [...a, v+1, v+2], [])
like image 45
Freewalker Avatar answered Sep 27 '22 06:09

Freewalker


using Array#concat and Array#map

Array.prototype.concat.apply([], [3, 16, 120].map(x => [x+1, x+2] ));
like image 28
eltonkamami Avatar answered Sep 30 '22 06:09

eltonkamami


Just for fun, an ES6 solution with a generator:

var arr = [3, 16, 120];

var [...result] = (function*() { for( i of arr){ yield ++i; yield ++i; }})();

console.log(result);
like image 23
Me.Name Avatar answered Sep 27 '22 06:09

Me.Name


Using Array.prototype.flat():

const doubled = [3, 16, 120].map(item => [item + 1, item + 2]).flat();

console.log(doubled)

Fair warning – not a standard method to this date (posted 12/2018).

like image 23
HynekS Avatar answered Sep 30 '22 06:09

HynekS