Skip to content Skip to sidebar Skip to footer

Flatten Nested Array Of Objects, Renaming Keys To An Iterator

I have an array of objects, with each object looking like the following (a poll response): { 'slug': '18-AZ-Gov-GE-DvF', 'name': '2018 Arizona Gubernatorial GE', 'tags': [], 'chart

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"