Search code examples
javascriptjsonobjectmappinglodash

How to use mapKeys and group values by key in JavaScript?


Initially, I'm having the object:

let root = {};
root["myRootNode"] = { 
   id1: {
     age: "17",
     name: "name1",
     surname: "surname1"                    
  },
   id2: {
     age: "11",
     name: "name2",
     surname: "surname2"                    
  },
   id3: {
     age: "25",
     name: "name1",
     surname: "surname3"                    
  }
};

And what I want to do with it, is to get it into the state:

"name1": [
  {
     age: "17",
     surname: "surname1"         
  },
  {
     age: "25",
     surname: "surname3"         
  }
],
"name2": [
    age: "11",
    surname: "surname2"        
]

For me it's important to have the list/array of all objects, which contains this same property, grouped by the value of that property.

What I tried (using lodash) is:

let test = _.mapKeys(root["myRootNode"], function(value, key) {
  return value["name"];
});

But this gives me the result:

"name1": {
   age: "25"
   name: "name1"
   surname: "surname3"
},
"name2": {
   age: "11"
   name: "name2"
   surname: "surname2"
}

So they are not grouped and only the last value is mapped under the key which is repeating. Also in the result that I got, they are not placed under an array.


Solution

  • Can use groupBy and map it's values to get rid of the name property.

    If you don't mind leaving the name property can simply do _.groupBy(root.myRootNode, 'name');

    Personally it feels like you should be using arrays instead of objects

    const res =
    _(root.myRootNode)
      .groupBy('name')
      .mapValues((arr)=>_.map(arr, (o) =>_.omit(o,['name'])))
      .value()
    
    
    
    console.log(res)
    <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>
    
    <script>
    let root = {};
    root["myRootNode"] = { 
       id1: {
         age: "17",
         name: "name1",
         surname: "surname1"                    
      },
       id2: {
         age: "11",
         name: "name2",
         surname: "surname2"                    
      },
       id3: {
         age: "25",
         name: "name1",
         surname: "surname3"                    
      }
    };
    </script>