Сгладить вложенный массив объектов, переименовав ключи в итератор - PullRequest
0 голосов
/ 10 мая 2018

У меня есть массив объектов, каждый из которых выглядит следующим образом (ответ на опрос):

{
"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
 }
]
},

Мне нужно сгладить массив, к которому обращается ключ responses, чтобы каждый объект имел ключ к своему итератору.

Конечный объект должен выглядеть так:

{
"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",
 "label1": "Ducey",
 "name1": "Doug Ducey",
 "party1": "Republican",
 "incumbent1": true
 "label2": "Farley",
 "name2": "Steve Farley",
 "party2": "Democrat",
 "incumbent2": false
 "label3": "Other",
 "name3": "Other",
 "party3": null,
 "incumbent3": false
 "label4": "Undecided",
 "name4": "Undecided",
 "party4": null,
  "incumbent4": false
},

Ответы , которые я видел , не переименовывают ключи объектов при выравнивании или выполняются в коллекции.

Я попробовал несколько решений, но хотел посмотреть, есть ли простой способ es6, прежде чем я действительно погрузлюсь.

Ответы [ 4 ]

0 голосов
/ 10 мая 2018

Вы можете структурировать свои ответы и другие данные, затем уменьшить каждый ответ до одного объекта с индексированными ключами и затем собрать результат с помощью оператора распространения объекта:

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 }
0 голосов
/ 10 мая 2018

Вы можете использовать forEach, чтобы пройти через массив responses и назначить новый ключ для вашего объекта для entries в каждом объекте. После этого просто delete исходный массив responses:

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 key
        Object.entries(item).forEach(([k, v]) => obj[k+(i+1)] = v)
    })
// no need for obj.responses any more
delete obj.responses
console.log(obj)
0 голосов
/ 10 мая 2018

Один подход будет использовать несколько новых вкусностей, включая spread, destructuring assignment, template literals, entries и самое главное reduce.

Основная идея заключается в использовании редуктора для преобразования массива responses в новый объект, причем каждый объект-элемент использует вторичный редуктор для дополнения ключа счетчиком итераторов и присвоения значения внешнему объекту с новым ключом.

Ключевым преимуществом этого подхода является то, что исходный объект (включая его подобъекты) не изменяется (читай: никаких побочных эффектов).

const flattened = responses.reduce((o, g, i) => {
    Object.entries(g).reduce((t, [k, v]) => {
      t[`${k}${i + 1}`] = v;
      return t;
    }, o);

    return o;
  },
  {});

Полный рабочий пример:

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});
0 голосов
/ 10 мая 2018

Использование массива .reduce метод может хорошо работать здесь. Поскольку обратный вызов reduce получит текущий индекс в качестве третьего аргумента, вы можете использовать его для создания ключей, которые вы ищете.

Пример:

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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...