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)
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.
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.
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 .
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.
I come up with one myself, using spread operator.
[].concat(...[3, 16, 120].map(x => [x+1, x+2]))
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]
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]; })));
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), []);
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), []));
Immutable solution, with the spread operator:
[3, 16, 120].reduce((a, v) => [...a, v+1, v+2], [])
using Array#concat
and Array#map
Array.prototype.concat.apply([], [3, 16, 120].map(x => [x+1, x+2] ));
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);
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).
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