Reputation: 1071
I have this:
[
{ list: [ [Object], [Object] ] },
{ head: [ [Object], [Object] ] }
]
And want to turn it into this:
{
list: [ [Object], [Object] ],
head: [ [Object], [Object] ]
}
So an array of objects into an object. It would be great to achieve this with lodash.
Upvotes: 20
Views: 28159
Reputation: 18690
With TypeScript:
interface State {
state: string;
name: string;
}
const states: State[] = [
{ state: "NY", name: "New York" },
{ state: "AZ", name: "Arizona" },
];
const statesObj = reduce<State, Record<string, string>>(
states,
(memo, { state, name }) => assign(memo, { [state]: name }),
{},
);
console.log(statesObj); // <-- {AZ: "Arizona"}, {NY: "New York"}
Upvotes: 0
Reputation: 44730
To build on @rcsole's great answer, this works well:
states = [{
state: "NY",
name: "New York",
}, {
state: "AZ",
name: "Arizona",
}]
statesObj = Object.assign({}, ...states.map(state => {
return { [state.state]: state.name }
}))
{
AZ: "Arizona",
NY: "New York",
}
Let's break this up into multiple pieces:
// Step 1: Transform from [{state: "Foo", name: "Bar"}, ...] to [{Foo: "Bar"}, ...]
mappedStates = states.map(state => { return { [state.state]: state.name } })
// Step 2: Merge all the objects in that array into a single new object
statesObj = Object.assign({}, ...mappedStates)
Step 1 uses map
to iterate over every item in the array (every state object). map
executes a function for every state
object and returns a new object with the state as the key and the name as the value. We need to surround state.state
in brackets because it's a dynamic value in an object literal.
Step 2 uses Object.assign
to merge all the new state objects in the mappedStates
array into a new object (the first parameter, {}
).
What are the three dots ...
for? That's the spread operator. It takes every element in the mappedStates
array and turns them into direct arguments of the Object.assign
method.
This example makes it clear:
Object.assign({}, ...mappedStates)
is the same as
Object.assign({}, {AZ: "Arizona"}, {NY: "New York"})
That's it!
Upvotes: 10
Reputation: 4515
_.reduce(array, function(memo, current) { return _.assign(memo, current) }, {})
Upvotes: 23
Reputation: 493
I think an even shorter solution would be:
Object.assign({}, ...array)
I know you asked for lodash, but it doesn't seem like you even need this way. Unless you want to use _.extend
.
Upvotes: 28
Reputation: 909
Use fromPairs on lodash 4. https://lodash.com/docs#fromPairs
_.fromPairs([['fred', 30], ['barney', 40]]);
Upvotes: 1
Reputation: 11211
Here's a shorter version:
_.transform(array, _.ary(_.extend, 2), {});
The transform() function is like reduce(), except it's not expecting you to return anything. Since extend() is altering it's first argument, we can just pass it straight to transform()
. It's wrapped in ary() to make sure it only gets 2 arguments passed to it.
Upvotes: 11