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
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')
//--
createdDateTime
properties are all identical... – CertainPerformance Commented Jan 23, 2019 at 9:51