Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to pass a custom comparator to lodash's sortBy function?

For example, I want to sort with respect to Intl.Collator().compare. Is there any way to pass this comparator to be used by _.sortBy?

like image 839
Daniel Avatar asked Apr 24 '17 19:04

Daniel


People also ask

Is Lodash Sortby stable?

Creates an array of elements, sorted in ascending order by the results of running each element in a collection thru each iteratee. This method performs a stable sort, that is, it preserves the original sort order of equal elements.

How do you use Sortby Lodash?

js. Lodash helps in working with arrays, collection, strings, objects, numbers etc. The _. sortBy() method creates an array of elements which is sorted in ascending order by the results of running each element in a collection through each iteratee.

How does Sortby work?

The SORTBY function sorts the contents of a range or array based on the values in a corresponding range or array. Note: This function is currently available to Microsoft 365 subscribers in Current Channel.

What is comparator function in c++?

Comparator Classes are used to compare the objects of user-defined classes. In order to develop a generic function use template, and in order to make the function more generic use containers, so that comparisons between data can be made.


2 Answers

actually iteratees can be mapping for the return result:

const users = [
  { 'user': 'fred',   'age': 48 },
  { 'user': 'barney', 'age': 36 },
  { 'user': 'fred',   'age': 40 },
  { 'user': 'barney', 'age': 34 }
];

_.sortBy(users, [function(o) { return o.user; }]);
// output: objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]]

or iteratees can be normal js sort function like i made in the below example to sort array of objects to sort cards when cardsStatus === 'NORI' so card should be on top of array

const cardsBeforeSort = [
              {
                "cardStatus": "NORM",
                "consumedLimit": 0,
                "cardAccountSerial": "10551880",
                "cashLimit": null,
                "applePayStatus": "ELIGIBLE",
                "embossName": "Hdhh",
                "nickName": "",
                "aan": "123",
                "balance": -9,
                "key": "405433******8106"
              },
              {
                "cardStatus": "NORI",
                "consumedLimit": 0,
                "cardAccountSerial": "10551908",
                "cashLimit": null,
                "applePayStatus": "ELIGIBLE",
                "embossName": "Hdhh",
                "nickName": "",
                "aan": "123",
                "balance": 1,
                "key": "405433******8382"
              },
              {
                "cardStatus": "HOLD",
                "consumedLimit": -169122.81,
                "cardAccountSerial": "10548192",
                "cashLimit": null,
                "applePayStatus": "ELIGIBLE",
                "embossName": "Hdjj",
                "nickName": "",
                "aan": "123",
                "balance": 5579.29,
                "key": "417323******3321"
              },
              {
                "cardStatus": "NORI",
                "consumedLimit": -7.74,
                "cardAccountSerial": "10549814",
                "cashLimit": null,
                "applePayStatus": "ELIGIBLE",
                "embossName": "Hdhh",
                "nickName": "",
                "aan": "123",
                "balance": 1,
                "key": "429927******1548"
              }
            ]
    
       const sortedCards = sortBy(userCards, [
          (first, second) =>
            first.cardStatus === 'NORI' ? -1 : second === 'NORI' ? 1 : 0,
        ]);

this will result in the following output:

console.log(sortedCards);
    [
          {
            "cardStatus": "NORI",
            "consumedLimit": -7.74,
            "cardAccountSerial": "10549814",
            "cashLimit": null,
            "applePayStatus": "ELIGIBLE",
            "embossName": "Hdhh",
            "nickName": "",
            "aan": "123",
            "balance": 1,
            "key": "429927******1548"
          },
          {
            "cardStatus": "NORI",
            "consumedLimit": 0,
            "cardAccountSerial": "10551908",
            "cashLimit": null,
            "applePayStatus": "ELIGIBLE",
            "embossName": "Hdhh",
            "nickName": "",
            "aan": "123",
            "balance": 1,
            "key": "405433******8382"
          },
          {
            "cardStatus": "NORM",
            "consumedLimit": 0,
            "cardAccountSerial": "10551880",
            "cashLimit": null,
            "applePayStatus": "ELIGIBLE",
            "embossName": "Hdhh",
            "nickName": "",
            "aan": "123",
            "balance": -9,
            "key": "405433******8106"
          },
          {
            "cardStatus": "HOLD",
            "consumedLimit": -169122.81,
            "cardAccountSerial": "10548192",
            "cashLimit": null,
            "applePayStatus": "ELIGIBLE",
            "embossName": "Hdjj",
            "nickName": "",
            "aan": "123",
            "balance": 5579.29,
            "key": "417323******3321"
          },
        ]

actually the benefit of using sortBy lodash function is being functional programming immutable solution because of not mutating cardsBeforeSort array

like image 96
Ramy El-Basyouni Avatar answered Sep 18 '22 07:09

Ramy El-Basyouni


No, unfortunately this is not currently possible.

A workaround is to use the iteratees function to map the values to something the standard comparator will sort correctly. This is however almost never practical.

It's also asked for here https://github.com/lodash/lodash/issues/246, but no response from the author.

like image 25
Mathias Bak Avatar answered Sep 17 '22 07:09

Mathias Bak