简体   繁体   中英

Creating array of objects using the properties from source array of objects based on grouping

I have an array of objects with the following structure:


    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} }
    ];


I need to take each key within each object inside array and form an array out of it. Basically grouping based on the key present in all the objects.If the object has no "values" it should return 0 across the val1,val2,val3 Help would be appreciated.

The resultant array of objects should look like:

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

I have tried so far:

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

You could reduce the array. Create an accumulator with each valx as key and { name: valx, data: [] } as it's value. Loop through the keys of each values and update the accumulator. Then use Object.values() to get the values of the merged object to get the desired output

 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)

Update:

If values is optional, you could check if values is undefined. But, if you need 0 when values doesn't exist, then another step is required. First, we need to get all the possible valx keys available in the array. Because, if { time: "14354545454", sum: 0} appears in the beginning of the array, there is no way of knowing what possible keys exist in the array. You can do this using flatMap and Set . Then loop through the set of keys for every object. If values doesn't exists, add a default 0 for the current valx key being looped.

 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))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM