【问题标题】:Creating array of objects using the properties from source array of objects based on grouping使用基于分组的源对象数组的属性创建对象数组
【发布时间】:2019-10-22 09:56:47
【问题描述】:

我有一个具有以下结构的对象数组:


    let sampleData = [
      { values: { val1: 4, val2: 5, val3: 7 } , time: "1571372233234" , sum: 16 },
      { values: { val1: 5, val2: 3, val3: 1 }, time: "1571372233234" , sum: 9},
      { time: "14354545454", sum: 0},
      { time: "14354545454", sum: 0} }
    ];


我需要获取数组内每个对象中的每个键并从中形成一个数组。基本上基于所有对象中存在的键进行分组。如果对象没有“值”,它应该在 val1,val2,val3 中返回 0 帮助将不胜感激。

生成的对象数组应如下所示:

result = [
  { name: 'val1', data: [4, 5, 0, 0] }, 
  { name: 'val2', data: [5, 3, 0, 0] }, 
  { name: 'val3', data: [7, 1, 0, 0] }
]

到目前为止我已经尝试过:

var result = sampleData.map(value => ({ value: value.values }));

【问题讨论】:

    标签: javascript arrays ecmascript-6


    【解决方案1】:

    您可以reduce 数组。创建一个累加器,每个 valx 作为键,{ name: valx, data: [] } 作为它的值。循环遍历每个values 的键并更新累加器。然后使用Object.values()获取合并对象的值得到想要的输出

    const sampleData = [
       { values: { val1: 4, val2: 5, val3: 7 } },
       { values: { val1: 5, val2: 3, val3: 1 }},
       { values: { val1: 4, val2: 7, val3: 2 } },
       { values: { val1: 5, val2: 1, val3: 5 } }
    ];
    
    const merged = sampleData.reduce((acc, { values }) => {
      for (const name in values) {
        acc[name] = acc[name] || { name, data: [] }
        acc[name].data.push(values[name])
      }
      return acc;
    }, {})
    
    const output = Object.values(merged)
    
    console.log(output)

    更新:

    如果values 是可选的,您可以检查values 是否未定义。但是,如果您在values 不存在时需要0,则需要另一个步骤。首先,我们需要获取数组中所有可能的valx 键。因为,如果{ time: "14354545454", sum: 0} 出现在数组的开头,则无法知道数组中存在哪些可能的键。您可以使用flatMapSet 执行此操作。然后循环遍历每个对象的键集。如果values 不存在,请为当前正在循环的valx 键添加默认0

    let sampleData = [
       { values: { val1: 4, val2: 5, val3: 7 } , time: "1571372233234" , sum: 16 },
       { values: { val1: 5, val2: 3, val3: 1 }, time: "1571372233234" , sum: 9},
       { time: "14354545454", sum: 0},
       { time: "14354545454", sum: 0}
    ];
    
    const keySet = new Set( sampleData.flatMap(a => Object.keys(a.values || {})) )
    
    const merged = sampleData.reduce((acc, { values = {} }) => {
      keySet.forEach(name => {
        acc[name] = acc[name] || { name, data: [] }
        acc[name].data.push(values[name] || 0)
      })
      return acc;
    }, {})
    
    console.log(Object.values(merged))

    【讨论】:

    • 一个小编辑。我已经更改了 sampleData 数组。我基本上是在尝试为堆积条形图准备数据。在您的上述答案中,我将如何处理;假设没有“值”对象,它应该在 val1,val2,val3 中返回 0,以便在绘制图形时它会显示为该时间间隔没有值
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-24
    • 2016-11-02
    • 2021-03-13
    • 1970-01-01
    • 1970-01-01
    • 2020-09-11
    相关资源
    最近更新 更多