Reputation: 1297
I have an array - types
- which looks something like this -
[
{"id": 1, "name": "Payment"},
{"id": 2, "name": "Debit"},
{"id": 3, "name": "Credit"},
{"id": 4, "name": "Transaction"}
]
I want to transform the array into another array which looks like this -
[
{"Payment": 1},
{"Debit": 2},
{"Credit": 3},
{"Transaction": 4}
]
When I do the following, the first entry is always missing -
const typeArray = types === null || types.length === 0 ? [] :
types.map((type) => {
const id = type.id;
const name = type.name;
return {[name]: id};
})
.reduce((prev, curr) => [...prev, curr]);
I always get the output something like this -
[
{"Debit": 2},
{"Credit": 3},
{"Transaction": 4}
]
When I instead use -
.reduce((prev, curr) => [prev, curr]);
I get a nested array, but all the elements are present. The array looks like so -
[
[
[
{"Payment":1},
{"Debit":2}
],
{"Credit":3}
],
{"Transaction":4}
]
How do I do this. Is there something like flatMap()
from RxJS
where I can merge all the arrays into a single array?
Upvotes: 0
Views: 342
Reputation: 386680
You could take a combination with Array#map
instead of Array#reduce
, because the accumulator is always the same and map
fits better for getting an array with a value for each element, destructuring assignment for the properties and computed property names for the key of a new object.
var data = [{ id: 1, name: "Payment" }, { id: 2, name: "Debit" }, { id: 3, name: "Credit" }, { id: 4, name: "Transaction" }],
result = data.map(({ id, name }) => ({ [name]: id }));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Upvotes: 1
Reputation: 125
One-liner reduce
const types = [
{"id": 1, "name": "Payment"},
{"id": 2, "name": "Debit"},
{"id": 3, "name": "Credit"},
{"id": 4, "name": "Transaction"}
]
const typeArrayReduce = types.reduce((acc, type) => acc.concat({[type.name]:type.id}), []);
console.log(typeArrayReduce);
Upvotes: -1
Reputation: 32145
Well you don't need the .reduce()
call, because Array.prototype.reduce()
applies a function against an accumulator and each element in the array (from left to right) to reduce it to a single value.
While Array.prototype.map()
creates a new array with the results of calling a provided function on every element in the calling array, and that's exactly what you need here.
This is how should be your code:
const typeArray = types === null || types.length === 0 ? [] :
types.map((type) => {
const id = type.id;
const name = type.name;
return {
[name]: id
};
});
Demo:
var types = [
{"id": 1, "name": "Payment"},
{"id": 2, "name": "Debit"},
{"id": 3, "name": "Credit"},
{"id": 4, "name": "Transaction"}
];
const typeArray = types === null || types.length === 0 ? [] :
types.map((type) => {
const id = type.id;
const name = type.name;
return {
[name]: id
};
});
console.log(typeArray);
Upvotes: 1
Reputation: 68665
Why you need to use reduce
? It gets your desired result without it. Just work with Array#map.
const types = [
{"id": 1, "name": "Payment"},
{"id": 2, "name": "Debit"},
{"id": 3, "name": "Credit"},
{"id": 4, "name": "Transaction"}
]
const typeArrayMap = types.map((type) => ({ [type.name]: type.id }));
console.log(typeArrayMap);
const typeArrayReduce = types.reduce( (array,type)=>{
array.push({[type.name]:type.id});
return array;
}, []);
console.log(typeArrayReduce);
Using Array#reduce for aggregate purposes
const people = [
{name: 'A', age: 7},
{name: 'B', age: 8},
{name: 'C', age: 9},
{name: 'D', age: 10},
];
const sumOfAges = people.reduce( (total, person) => total + person.age, 0 );
console.log(sumOfAges);
Upvotes: 1
Reputation: 48407
You should use map
method which accepts as parameter a callback function in order to obtain a cleaner
solution.
The map() method creates a new array with the results of calling a provided function on every element in the calling array.
let array=[
{"id": 1, "name": "Payment"},
{"id": 2, "name": "Debit"},
{"id": 3, "name": "Credit"},
{"id": 4, "name": "Transaction"}
]
array=array.map(function(item){
return {[item.name]:item.id};
});
console.log(array);
or using arrow
functions:
array=array.map(item=> {[item.name]:item.id});
Also, you can use reduce
function in this way:
let array=[
{"id": 1, "name": "Payment"},
{"id": 2, "name": "Debit"},
{"id": 3, "name": "Credit"},
{"id": 4, "name": "Transaction"}
]
array=array.reduce((arr,item)=>{
arr.push({[item.name]:item.id});
return arr;
},[]);
console.log(array);
Upvotes: 3
Reputation: 29926
Your code throws an exception in Chrome, see:
console.log([1,2,3].reduce((a,b)=>[...a,b]));
The reason: .reduce
has two arguments. The second one is the initial value of prev
:
console.log([1,2,3].reduce((a,b)=>[...a,b], []));
But as others already pointed out: you don't need reduce here. Your sequence is already an array, and even if it wasn't there would be better ways to convert it to an array.
Upvotes: 0
Reputation: 1442
Use map
like this:
let data = [
{"id": 1, "name": "Payment"},
{"id": 2, "name": "Debit"},
{"id": 3, "name": "Credit"},
{"id": 4, "name": "Transaction"}
];
let result = data.map((elem) => ({ [elem.name]: elem.id }));
console.log(result);
Upvotes: 1