Search code examples
javascriptarraysreactjssortingcollections

Sort and group objects alphabetically by first letter Javascript


Im trying to create a collection like this in order to use in a react component:

let data = [
    { 
        group : 'A', 
        children : [
            { name : 'Animals', id : 22 },
            ...
        ]
    },
    { 
        group : 'B', children : [
            { name : 'Batteries', id : 7},
            { name : 'Baggage', id : 12 },
            ...
        ]
    },
    { 
        group : 'C', children : [
            { name : 'Cake', id : 7},
            ...
        ]
    },
]

 I've already sort my data like this :

let rawData = [
    { name : 'Animals', id : 10},
    { name : 'Batteries', id : 7},
    { name : 'Baggage', id : 12 },
    { name : 'Cake', id : 7},
    ...
]

Also I used this sorting method but the problem is, it's returning an Object with A, B, C keys with children as values. But I have to turn it into array like above in order to use that.

Here is what i've tried so far :

let data = rawData.reduce(function(prevVal, newVal){   
    char = newVal.name[0].toUpperCase();
    return { group: char, children :{name : newVal.name, id : newVal.id}};
},[])

Solution

  • You can create object with reduce and then use Object.values on that object.

    let rawData = [
      { name : 'Animals', id : 10},
      { name : 'Batteries', id : 7},
      { name : 'Baggage', id : 12 },
      { name : 'Cake', id : 7},
    ]
    
    let data = rawData.reduce((r, e) => {
      // get first letter of name of current element
      let group = e.name[0];
      // if there is no property in accumulator with this letter create it
      if(!r[group]) r[group] = {group, children: [e]}
      // if there is push current element to children array for that letter
      else r[group].children.push(e);
      // return accumulator
      return r;
    }, {})
    
    // since data at this point is an object, to get array of values
    // we use Object.values method
    let result = Object.values(data)
    
    console.log(result)