如何按名称排序(以lodash降序)?

时间:2019-01-23 09:48:48

标签: javascript lodash

我有一个按日期降序排列的对象数组:

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

这是数组:

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"
      }
    ]
  }

}

排序按日期desc返回正确的顺序。在此示例中,日期是相同的。仅在这种情况下,我要按(申请人)lastName排序,其中isPrimaryApplicant = true?链接到codepen

3 个答案:

答案 0 :(得分:2)

Loadash sortBy不提供比较器功能的选项(尽管还有其他实现方法)

您可以使用数组排序方法来实现此目的:

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;
    }
})

答案 1 :(得分:1)

本来会喜欢使用lodash的,但是文档并不能反映现实。 _.sortBy的第二个参数是文档中的一个数组,但是如果我传递一个函数数组,则该参数不起作用。

您可以将名称添加到警报中,同时在其上添加用于排序的sortDate:

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>

答案 2 :(得分:0)

您需要lodash的orderBy,它允许排序方向。

您可以将ascdesc附加到您使用的每个排序属性。

这应该为您寻找所需的订单:

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