简体   繁体   中英

object is sorted but its keys are not preserved using lodash sortBy

Context

Need to sort following Objects by readingDate using lodash, I'm able to sort it but its indexes are not preserved.

Original JSON Object

{
    "Inventory Creation": [
      {
        "id": 150,
        "reading": "12345",
        "readingDate": "2020-07-14"
      }
    ],
    "Inventory & Check-in": [
      {
        "id": 151,
        "reading": "12345",
        "readingDate": "2020-11-14"
      }
    ],
    "Check-in": [
      {
        "id": 152,
        "reading": "12345",
        "readingDate": "2020-08-14"
      }
    ]
}

Code Which I've Tried

_.sortBy(unsorted, o => o[0].readingDate).reverse();

here unsorted contains the above Orignal JSON object

Actual Result (What I'm getting)

{
    0: [
      {
        "id": 151,
        "reading": "12345",
        "readingDate": "2020-11-14"
      }
    ],
    1: [
      {
        "id": 152,
        "reading": "12345",
        "readingDate": "2020-08-14"
      }
    ],
    2: [
      {
        "id": 150,
        "reading": "12345",
        "readingDate": "2020-07-14"
      }
    ]
}

Expected Result (What I want)

{
    "Inventory & Check-in": [
      {
        "id": 151,
        "reading": "12345",
        "readingDate": "2020-11-14"
      }
    ],
    "Check-in": [
      {
        "id": 152,
        "reading": "12345",
        "readingDate": "2020-08-14"
      }
    ],
    "Inventory Creation": [
      {
        "id": 150,
        "reading": "12345",
        "readingDate": "2020-07-14"
      }
    ]
}

Here are the steps:

  • transform the object to list of key-value pairs ( _.toPairs() or built-in's Object.entries() )
  • sort the list
  • transform list of key-value pairs back to object ( _.fromPairs() or built-in's Object.fromEntries() )

Below snippet could help you. I use _.chain() for better readability

 const data = { "Inventory Creation": [ { id: 150, reading: "12345", readingDate: "2020-07-14", }, ], "Inventory & Check-in": [ { id: 151, reading: "12345", readingDate: "2020-11-14", }, ], "Check-in": [ { id: 152, reading: "12345", readingDate: "2020-08-14", }, ], } const res = _.chain(data).toPairs().sortBy((p) => p[1][0].readingDate).reverse().fromPairs().value() console.log(res)
 <script src="https://cdn.jsdelivr.net/npm/lodash@4.17.19/lodash.min.js"></script>

This is a combination of collections/arrays. Look at the lodash function you are using and what it is used for. This cannot work, you are trying to use an array-function of an Object. The function does exactly what it should, sorting the array. But there is no way to create the sorted object this way, it (meaning the lodash function) doesn't even know about the object.

Having said this, here is a working solution (look at map/reduce in general):

const entries = Object.entries(unsortedArr);
const sorted = entries.sort((a,b) => a[1][0].readingDate < b[1][0].readingDate ? 1 : -1);
const reduced = sorted.reduce(
  (acc, obj) => {
    acc[obj[0]] = obj[1]
return acc},{});

Ofc you can chain these calls, but I tried to make it more understandable.
I just stumbled upon groupBy which could be used, too.

Here is a brute force solution. First sort the array and also store the keys. Then Form the array with keys from the sortedArray.

var sortedArray = _.sortBy(unsortedArray, function(val, key){
    val[0].key = key;
    return val[0].readingDate;
}).reverse();

var sortedArrayWithIndex = {};

_.each(sortedArray, function(val){
    var key = val[0].key;
    delete val[0].key;
    sortedArrayWithIndex[key] = val;
});
console.log(sortedArrayWithIndex);

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