Reputation: 1797
I need to sort the main data by the oldest created account. In the example below, the first element in the list would be id = 2. That's because the id = 2 contains the oldest created account (named account3, which was created at 2020-10-05, while the other accounts have been created after that date). I'm using nodejs. Is there an es-function that can solve this problem in an easy way?
The object data looks like this:
{
"data": [{
"id": 1,
"accounts": [{
"id": 333,
"data": {
"name": "account1",
"createdAt": "2020-10-07T09:27:28.032Z"
}
}]
}, {
"id": 2,
"accounts": [{
"id": 334,
"data": {
"name": "account2",
"createdAt": "2020-10-06T09:27:28.032Z"
}
}, {
"id": 335,
"data": {
"name": "account3",
"createdAt": "2020-10-05T09:27:28.032Z"
}
}]
}]
}
Upvotes: 0
Views: 58
Reputation: 2679
const data = [{
"id": 1,
"accounts": [{
"id": 333,
"data": {
"name": "account1",
"createdAt": "2020-10-07T09:27:28.032Z"
}
}]
}, {
"id": 2,
"accounts": [{
"id": 334,
"data": {
"name": "account2",
"createdAt": "2020-10-06T09:27:28.032Z"
}
}, {
"id": 335,
"data": {
"name": "account3",
"createdAt": "2020-10-05T09:27:28.032Z"
}
}]
}]
const sorted = data.sort((a, b) => {
const aOldestDate = a.accounts.reduce((acc, item) => {
const itemDate = new Date(item.data.createdAt);
return itemDate < acc && itemDate || acc;
}, new Date());
const bOldestDate = b.accounts.reduce((acc, item) => {
const itemDate = new Date(item.data.createdAt);
return itemDate < acc && itemDate || acc;
}, new Date());
return aOldestDate - bOldestDate;
});
console.log(sorted);
Upvotes: 1
Reputation: 43718
You can often solve this problem with map
--> sort
--> map
.
It does 3 passes on the input but remains O(n log n)
. You could further optimize, but I doubt this becomes a bottleneck.
Map to [record, oldestAccountDate]
tuples.
Sort the tuples by oldestAccountDate
.
Map again to unwrap the record.
const wrapper = {
"data": [{
"id": 1,
"accounts": [{
"id": 333,
"data": {
"name": "account1",
"createdAt": "2020-10-07T09:27:28.032Z"
}
}]
}, {
"id": 2,
"accounts": [{
"id": 334,
"data": {
"name": "account2",
"createdAt": "2020-10-06T09:27:28.032Z"
}
}, {
"id": 335,
"data": {
"name": "account3",
"createdAt": "2020-10-05T09:27:28.032Z"
}
}]
}]
};
wrapper.data = wrapper.data
.map(rec => [rec, Math.min(...rec.accounts.map(acc => new Date(acc.data.createdAt)))])
.sort((a, b) => a[1] - b[1])
.map(tuple => tuple[0]);
console.log(wrapper);
Upvotes: 1