0

i want the result below

Given an array

[{
      "date": "JAN",
      "value": 5,
      "weight": 3
  }, {
      "date": "JAN",
      "value": 4,
      "weight": 23
  }, {
      "date": "FEB",
      "value": 9,
      "weight": 1
  }, {
      "date": "FEB",
      "value": 10,
      "weight": 30
  }]

and a key 'date'
transform it into following output:

 [{
       "date": "JAN",
       "value": [5, 4],
       "weight": [3, 23]
   }, {
       "date": "FEB",
       "value": [9, 10],
       "weight": [1, 30]
   }]

any help would be much appreciated thank You in advance

  • 1
    Does this answer your question? [How to group an array of objects by key?](https://stackoverflow.com/questions/54177679/how-to-group-an-array-of-objects-by-key) – Anurag Srivastava Feb 12 '22 at 16:02

1 Answers1

0
  • Using Array#reduce, iterate over the array while updating a Map where the primaryKey is the key and the grouped object is the value
  • In every iteration:
    • get the primary-key value and the remaining properties from the current object
    • Using Object#entries, get the list of pairs from the properties
    • Using Map#get, get the current primary-key value if exists
    • If it does, we need to iterate over the entries using Array#forEach and update the arrays
    • If not, we create the initial object and add a new pair using Map#set
  • Finally, using Map#values, you can get the list of grouped objects

const transform = (arr, primaryKey) => 
  [...
    arr.reduce((map, e) => {
    
      const { [primaryKey]: key, ...props } = e;
      const currentProps = Object.entries(props);
      const item = map.get(key);
      
      if(item) {
        currentProps.forEach(([ k, v ]) => item[k] = [...(item[k] ?? []), v]);
      } else {
        const obj = currentProps.reduce((acc, [ k, v ]) => ({
          ...acc, [k]: Array.isArray(v) ? [...v] : [v]
        }), { primaryKey: key });
        map.set(key, obj);
      }
      
      return map;
    }, new Map)
    .values()
  ];


console.log( transform([ { "date": "JAN", "value": 5, "weight": 3 }, { "date": "JAN", "value": 4, "weight": 23 }, { "date": "FEB", "value": 9, "weight": 1 }, { "date": "FEB", "value": 10, "weight": 30 } ], 'date') );
console.log( transform([ { type: '200', api: [ '/counter' ] }, { type: '400', api: [ '/counter' ] }, { type: '500', api: [ '/counter', '/product' ] } ], 'type') );
Majed Badawi
  • 27,616
  • 4
  • 25
  • 48
  • can we make it a general solution like if we have different key then also it should work, i mean { date, value, weight } why use them hard coded –  Feb 12 '22 at 20:12
  • For example i have this data set as well [ { type: '200', api: [ '/counter' ] }, { type: '400', api: [ '/counter' ] }, { type: '500', api: [ '/counter', '/product' ] } ] as in that we have diffrent primaryKey I want a solution in which i can pass array and primaryKey(on which i will do compare ) –  Feb 12 '22 at 20:13
  • I am trying to solve this problem basically https://leetcode.com/playground/NfECNd95 –  Feb 12 '22 at 20:17
  • 1
    Thank you for the answer with explanation as well –  Feb 13 '22 at 05:31