简体   繁体   中英

How to sort object according to nested array elements

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

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.

  1. Map to [record, oldestAccountDate] tuples.

  2. Sort the tuples by oldestAccountDate .

  3. 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);

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM