Search code examples
javascriptobjectlodashjavascript-objects

Sort Object by children value using lodash


I have the following Object:

const object = {
  "9c8vDTruRDPi937aHMMz":{
    name: "item1",
    createdAt: {
      seconds: 1582227276, 
      nanoseconds: 68000000
    }
  },
  "rAexYu2rAz0AEnD77x5p":{
    name: "item2",
    createdAt: {
      seconds: 1582227577,
      nanoseconds: 922000000
    }
  }
}

And would like to sort it depending on createdAt.seconds and keeping it as an object.

For example, the return value would be (if sorting depending on seconds and Desc):

const sortedByDateObject = {
  "rAexQu3rdm0AEnD77x5p":{
    name: "item2",
    createdAt: {
      seconds: 1582227577,
      nanoseconds: 922000000
    }
  },
  "9c8vDGryRSZi817aHMMz":{
    name: "item1",
    createdAt: {
      seconds: 1582227276, 
      nanoseconds: 68000000
    }
  }
}

Know how to sort arrays with lodash, but not this kind of complex task with nested objects.

Any help is much appreaciated :)


Solution

  • This will turn your object into an array that can be properly sorted (as pointed out by @Taki, object property order is not guaranteed).

    const object = {
      "9c8vDTruRDPi937aHMMz":{
        name: "item1",
        createdAt: {
          seconds: 1582227276, 
          nanoseconds: 68000000
        }
      },
      "rAexYu2rAz0AEnD77x5p":{
        name: "item2",
        createdAt: {
          seconds: 1582227577,
          nanoseconds: 922000000
        }
      }
    };
    
    const orderedArray = _.chain(object)
      .toPairs()
      .map(([key, ...obj]) => ({
        key,
        ...obj[0],
        createdAtSeconds: obj[0].createdAt.seconds
      }))
      .orderBy(['createdAtSeconds'], ['desc'])
      .map(({ createdAtSeconds, ...obj }) => obj)
      .value()
      
    console.log(orderedArray);
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/lodash.min.js"></script>