Преобразование объекта с вложенными объектами в массив объектов, перегруппированных по внутренним ключам объекта. - PullRequest
0 голосов
/ 08 мая 2020

У меня есть следующий JavaScript объект JSON1

{
"1": {
    "Average": 32.31,
    "Count": 19,
    "Sum": 32.6,
    "Color": "red"
},
"2": {
    "Average": 32.72,
    "Count": 18,
    "Sum": 32.96,
    "Color": "blue"
},
"3": {
    "Average": 31.4,
    "Count": 18,
    "Sum": 31.48,
    "Color": "green"
}
} 

, и я хочу преобразовать в следующий формат, используя методы javascript ES6. JSON2

[{
"title": "Average",
"val1": 32.31,
"val2": 32.72,
"val3": 31.4
}, {
"title": "Count",
"val1": 19,
"val2": 18,
"val3": 18
}, {
"title": "Sum",
"val1": 32.6,
"val2": 32.96,
"val3": 31.48
}, {
"title": "Color",
"val1": "red",
"val2": "blue",
"val3": "green"
}]


 Object.keys(json1).forEach((item, index) => {
      let statsList = [];
      Object.keys(json1[item]).forEach(objItem => {
        statsList.push({
          title: objItem,
          val1: boxObj[1][objItem],
          val2: boxObj[2][objItem],
          val3: boxObj[3][objItem]
        });
      });
 console.log(statsList)
    });

var json1 = {
  "1": {
    "Average": 32.31,
    "Count": 19,
    "Sum": 32.6,
    "Color": "red"
  },
  "2": {
    "Average": 32.72,
    "Count": 18,
    "Sum": 32.96,
    "Color": "blue"
  },
  "3": {
    "Average": 31.4,
    "Count": 18,
    "Sum": 31.48,
    "Color": "green"
  }
};

Object.keys(json1).forEach((item, index) => {
  let statsList = [];
  Object.keys(json1[item]).forEach(objItem => {
    statsList.push({
      title: objItem,
      val1: boxObj[1][objItem],
      val2: boxObj[2][objItem],
      val3: boxObj[3][objItem]
    });
  });
  console.log(statsList)
});

Здесь, в JSON1, количество объектов может быть любым. Он должен форматировать его динамически. В JSON2 вместо val1, val2 можно использовать все, что угодно, однозначно идентифицируемые ключи во всех объектах, присутствующих в массиве. Я пробовал использовать forEach, мне удалось добиться этого с предоставленными ключами stati c и с несколькими операторами цикла. Я просто хочу использовать ключи Dynami c и избегать множественных циклов, и я хочу знать, как лучше и проще всего выполнить это форматирование в Javascript. Аванс Спасибо за вашу помощь.

Ответы [ 2 ]

2 голосов
/ 08 мая 2020

Вы можете пройти источник Object.values() с помощью Array.prototype.reduce(), чтобы создать объект, который сопоставит каждую категорию со всеми возможными значениями.

Затем вы может Array.prototype.map() в результате Object.entries() чтобы вернуть массив объектов с желаемой структурой:

const src = {"1":{"Average":32.31,"Count":19,"Sum":32.6,"Color":"red"},"2":{"Average":32.72,"Count":18,"Sum":32.96,"Color":"blue"},"3":{"Average":31.4,"Count":18,"Sum":31.48,"Color":"green"}},

    resultMap = Object
      .values(src)
      .reduce((r,o,i) => (
        Object
         .entries(o)
         .forEach(([key,value]) => 
          (r[key]=r[key]||{}, r[key][`value${i+1}`] = value))
       ,r),{}),
       
    result = Object
      .entries(resultMap)
      .map(([name,{...values}]) => ({name,...values}))
       
console.log(result)
.as-console-wrapper{min-height:100%;}

Если требуются только уникальные элементы в каждой категории, вы можете несколько изменить вышеуказанное решение, используя Set():

const src = {"1":{"Average":32.31,"Count":19,"Sum":32.6,"Color":"red"},"2":{"Average":32.72,"Count":18,"Sum":32.96,"Color":"blue"},"3":{"Average":31.4,"Count":18,"Sum":31.48,"Color":"green"}},

    resultMap = Object
      .values(src)
      .reduce((r,o,i) => (
        Object
         .entries(o)
         .forEach(([key,value]) => 
          (r[key]=r[key]||(new Set()), r[key].add(value)))
       ,r),{}),
       
    result = Object
      .entries(resultMap)
      .map(([name,values]) => ({
        name, 
        ...([...values].reduce((r,v,i) => (r[`value${i+1}`]=v, r),{}))
      }))
       
console.log(result)
.as-console-wrapper{min-height:100%;}
1 голос
/ 08 мая 2020

Вы можете видеть свои данные в виде матрицы: каждая строка - это функция, а каждый столбец - измерение

  • У вас есть данные, выраженные строками
  • И что бы вы как данные, выраженные в виде столбцов
  • Итак, вы хотите транспонировать вашу матрицу

Давайте вспомним, что транспонирование может быть выполнено как: T[j][i] = M[i][j] forall i,j

В вашем случае

for each index of row i in M
  for each index of column j in M
    // T[j] is your aggregated record
    // i being the index of the row has to be renamed 'val'+i
    // and you add the property: title: columnOfJ to record T[j]
    T[j]['val' + i] = M[i][j]
    T[j].title = col corresponding to index j

const M = {"1":{"Average":32.31,"Count":19,"Sum":32.6,"Color":"red"},"2":{"Average":32.72,"Count":18,"Sum":32.96,"Color":"blue"},"3":{"Average":31.4,"Count":18,"Sum":31.48,"Color":"green"}}
const T = []
Object.entries(M).forEach(([i, Mi]) => {
  Object.keys(Mi).forEach((col, j) => {
    T[j] = T[j] || {}
    T[j].title = col // we just put the title before so it is the first entry in your record...
    T[j]['val' + i] = Mi[col]
  })
})
console.log(T)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...