Flatten Nested Array Of Objects, Renaming Keys To An Iterator
Solution 1:
Using the array .reduce
method might work well here. Since the reduce
callback will receive the current index as the third argument, you can use that to create the keys you're looking for.
Example:
const myArray = [
{
"label": "Ducey",
"name": "Doug Ducey",
"party": "Republican",
"incumbent": true
},
{
"label": "Farley",
"name": "Steve Farley",
"party": "Democrat",
"incumbent": false
},
{
"label": "Other",
"name": "Other",
"party": null,
"incumbent": false
},
{
"label": "Undecided",
"name": "Undecided",
"party": null,
"incumbent": false
}
]
const flattened = myArray.reduce((flat, item, index) => ({
...flat,
...Object.keys(item).reduce((numbered, key) => ({
...numbered,
[key + (index+1)]: item[key],
}), {}),
}), {});
console.log(flattened);
Solution 2:
You can use forEach
to go through the responses
array and assign a new key on your object for the entries
in each object. After that just delete
the original responses
array:
let obj = {"slug": "18-AZ-Gov-GE-DvF","name": "2018 Arizona Gubernatorial GE","tags": [],"charts": [],"election_date": "2018-11-06","n_polls": 1,"created_at": "2017-06-13T13:32:26.000Z","responses": [ { "label": "Ducey", "name": "Doug Ducey", "party": "Republican", "incumbent": true }, { "label": "Farley", "name": "Steve Farley", "party": "Democrat", "incumbent": false }, { "label": "Other", "name": "Other", "party": null, "incumbent": false }, { "label": "Undecided", "name": "Undecided", "party": null, "incumbent": false }]}
obj.responses.forEach((item, i) => {
// item is one object from responses// i is the index starting at 0. Concat that on the keyObject.entries(item).forEach(([k, v]) => obj[k+(i+1)] = v)
})
// no need for obj.responses any moredelete obj.responsesconsole.log(obj)
Solution 3:
One approach would use a few of the newer goodies including spread
, destructuring assignment
, template literals
, entries
and most importantly reduce
.
The main gist is using a reducer to convert the responses
array to a new object with each element object using a secondary reducer to amend the key with the iterator count and assigning the value to the outer object with the new key.
A key benefit of this approach is the original object (including its sub-objects) are not modified (read: no side-effects).
const flattened = responses.reduce((o, g, i) => {
Object.entries(g).reduce((t, [k, v]) => {
t[`${k}${i + 1}`] = v;
return t;
}, o);
return o;
},
{});
Full working example:
const orig = {
"slug": "18-AZ-Gov-GE-DvF",
"name": "2018 Arizona Gubernatorial GE",
"tags": [],
"charts": [],
"election_date": "2018-11-06",
"n_polls": 1,
"created_at": "2017-06-13T13:32:26.000Z",
"responses": [{
"label": "Ducey",
"name": "Doug Ducey",
"party": "Republican",
"incumbent": true
},
{
"label": "Farley",
"name": "Steve Farley",
"party": "Democrat",
"incumbent": false
},
{
"label": "Other",
"name": "Other",
"party": null,
"incumbent": false
},
{
"label": "Undecided",
"name": "Undecided",
"party": null,
"incumbent": false
}
]
};
const {responses, ...foo} = orig;
const flattened = responses.reduce((o, g, i) => {
Object.entries(g).reduce((t, [k, v]) => {
t[`${k}${i + 1}`] = v;
return t;
}, o);
return o;
},
{});
console.log({flattened: {...foo, ...flattened}});
console.log({orig});
Solution 4:
You can destructure your responses and other data, then reduce each response to one object with indexed keys and then assemble result by object spread operator:
const { responses, ...other } = data
const indexedResponses = responses.reduce((acc, r, i) => {
Object.entries(r).forEach(([key, value]) => {
acc[`${key}${i + 1}`] = value
})
return acc
}, {})
const result = { ...other, ...indexedResponses }
Post a Comment for "Flatten Nested Array Of Objects, Renaming Keys To An Iterator"