javascript - How to sort by name descending in lodash? - Stack Overflow

admin2025-02-14  18

I have an array of objects that are sorted in descending order by date:

_.sortBy
  (persons.entities.alerts,
  dateObj => new Date(dateObj.createdDateTime)
).reverse()

This is the array:

let persons={
  "entities": {
    "applicants": [
      {
        "lastName": "Agamemnon",
        "isPrimaryApplicant": true,
        "id": "16671520038"
      },
      {
        "lastName": "Purdy",
        "isPrimaryApplicant": false,
        "id": "16671520039"
      },
      {
        "lastName": "Brekky",
        "isPrimaryApplicant": true,
        "id": "16671520040"
      },
      {
        "lastName": "Tabouli",
        "isPrimaryApplicant": true,
        "id": "16671520041"
      }
    ],
    "alerts": [
      {
        "createdDateTime": "2018-06-14T00:00:00.000Z",
        "applicants": ["16671520038", "16671520039"],
        "id": "05025fea-ec37-4767-a868-a646597365d0"
      },
      {
        "createdDateTime": "2018-06-14T00:00:00.000Z",
        "applicants": ["16671520040"],
        "id": "19d0da63-dfd0-4c00-a13a-cc822fc83869"
      },
      {
        "createdDateTime": "2018-06-14T00:00:00.000Z",
        "applicants": ["16671520041"],
        "id": "c5385595-2104-409d-a676-c1b57346f63e"
      }
    ]
  }

}

The sort returns the correct order by date desc. In this sample the dates are the same. Only in this case i want to sort by (applicants) lastName where isPrimaryApplicant=true? Link to codepen

I have an array of objects that are sorted in descending order by date:

_.sortBy
  (persons.entities.alerts,
  dateObj => new Date(dateObj.createdDateTime)
).reverse()

This is the array:

let persons={
  "entities": {
    "applicants": [
      {
        "lastName": "Agamemnon",
        "isPrimaryApplicant": true,
        "id": "16671520038"
      },
      {
        "lastName": "Purdy",
        "isPrimaryApplicant": false,
        "id": "16671520039"
      },
      {
        "lastName": "Brekky",
        "isPrimaryApplicant": true,
        "id": "16671520040"
      },
      {
        "lastName": "Tabouli",
        "isPrimaryApplicant": true,
        "id": "16671520041"
      }
    ],
    "alerts": [
      {
        "createdDateTime": "2018-06-14T00:00:00.000Z",
        "applicants": ["16671520038", "16671520039"],
        "id": "05025fea-ec37-4767-a868-a646597365d0"
      },
      {
        "createdDateTime": "2018-06-14T00:00:00.000Z",
        "applicants": ["16671520040"],
        "id": "19d0da63-dfd0-4c00-a13a-cc822fc83869"
      },
      {
        "createdDateTime": "2018-06-14T00:00:00.000Z",
        "applicants": ["16671520041"],
        "id": "c5385595-2104-409d-a676-c1b57346f63e"
      }
    ]
  }

}

The sort returns the correct order by date desc. In this sample the dates are the same. Only in this case i want to sort by (applicants) lastName where isPrimaryApplicant=true? Link to codepen

Share Improve this question edited Jan 23, 2019 at 11:14 bier hier asked Jan 23, 2019 at 9:48 bier hierbier hier 22.6k44 gold badges102 silver badges174 bronze badges 3
  • Note that your createdDateTime properties are all identical... – CertainPerformance Commented Jan 23, 2019 at 9:51
  • Yes, only when the dates are the same i want to sort by name. If the dates are different just by date. – bier hier Commented Jan 23, 2019 at 10:00
  • What name does an alert have? it looks like an alert can have multiple applicants and the applicants array has objects with name property. – HMR Commented Jan 23, 2019 at 10:23
Add a comment  | 

4 Answers 4

Reset to default 12

You want lodash's orderBy, which allows sort directions.

You can attach asc or desc to each sort property you use.

This should get you the ordering you're looking for:

_.orderBy(persons.entities.applicants, ['lastName'], ['desc'])

Loadash sortBy doesn't provide option for comparator function(though there are other ways to achieve it)

You can use array sort method to achieve this:

persons.entities.alerts.sort(function(a1, a2) { 
    if(a1.createdDateTime === a2.createdDateTime) {
        let applicant1 = persons.entities.applicants.find(a => a.id === a1.applicants[0]);
        let applicant2 = persons.entities.applicants.find(a => a.id === a2.applicants[0]);
        if (!applicant1.isPrimaryApplicant || applicant1.lastName < applicant2.lastName) {
           return -1;
       }
       return 1;

    } else {
        let d1 = new Date(a1.createdDateTime);
        let d2 = new Date(a2.createdDateTime);
        return d2 - d1;
    }
})

Would have loved to use lodash for this but the documentation does not reflect reality. The second argument to _.sortBy is an array in documentation but doesn't work if I pass an array of functions.

You can add names to your alerts and while your at it add a sortDate to use for sorting:

const persons={"entities":{"applicants":[{"lastName":"Agamemnon","isPrimaryApplicant":true,"id":"16671520038"},{"lastName":"Purdy","isPrimaryApplicant":false,"id":"16671520039"},{"lastName":"Brekky","isPrimaryApplicant":true,"id":"16671520040"},{"lastName":"Tabouli","isPrimaryApplicant":true,"id":"16671520041"}],"alerts":[{"createdDateTime":"2018-06-14T00:00:00.000Z","applicants":["16671520038","16671520039"],"id":"05025fea-ec37-4767-a868-a646597365d0"},{"createdDateTime":"2018-06-14T00:00:00.000Z","applicants":["16671520041"],"id":"19d0da63-dfd0-4c00-a13a-cc822fc83869"},{"createdDateTime":"2019-06-14T00:00:00.000Z","applicants":["16671520040"],"id":"c5385595-2104-409d-a676-c1b57346f63e"}]}}

const applicantsById = persons.entities.applicants.reduce(
    (result, applicant) => result.set(applicant.id, applicant),
    new Map(),
);
const alertsWithName = persons.entities.alerts.map((alert) => ({
    ...alert,
    sortDate:new Date(alert.createdDateTime).getTime(),
    name: (alert.applicants
        .map((id) => applicantsById.get(id))
        .filter((x) => x) //remove empty
        .find((applicant)=>applicant.isPrimaryApplicant)||{lastName:''}).lastName
}));

//according to not correct lodash documentation here:
//https://lodash.com/docs/4.17.11#sortBy
//we should be able to do this:
// console.log(
//   _.sortBy(alertsWithName, [
//     (alert) => new Date(alert.createdDateTime),
//     (alert) => alert.name,
//   ])
// )
//however that's not going to work so can try array sort method

console.log(
  alertsWithName.sort(
    (a,b)=>b.sortDate-a.sortDate || a.name.localeCompare(b.name)
  )
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.core.js"></script>

You could sort first then reverse

  //====SORT====
  sortArray(list: any[], field: string): any[] {
    return list = _.sortBy(list.sort(), field).reverse()
  }

//--
    this.yourList = this.sortArray(this.yourList , 'createdDateTime')
//--
转载请注明原文地址:http://conceptsofalgorithm.com/Algorithm/1739501850a109466.html

最新回复(0)