简体   繁体   中英

Sort array of objects by nested property with lodash

I have an array of objects like this

[{ 'a': { id: 4 }}, { 'b': { id: 3 }}, { 'c': { id: 2 }}, { 'd': { id: 5 }}]

I want to know with lodash the sorting of the objects according to the id. I would expect to receive something like ['d', 'a', 'b', 'c'] .

I tried to search this but I didn't find an answer which works with different keys in each object. I tried to do this with lodash' different functions (many). So I thought there may be a good and maybe short way to solve this.

Here is a plain JavaScript solution.

Since you want to get the sorted keys as the result, this solution does not modify the original array, thanks to the first map before sort :

 const data = [{ 'a': { id: 4 }}, { 'b': { id: 3 }}, { 'c': { id: 2 }}, { 'd': { id: 5 }}]; const sorted = data .map(x => Object.entries(x)[0]) .sort((a, b) => b[1].id - a[1].id) .map(x => x[0]); console.log(sorted); 

If you don't care about mutating the original array, you can directly sort using Object.values() and then return the first key with Object.keys() :

 const data = [{ 'a': { id: 4 }}, { 'b': { id: 3 }}, { 'c': { id: 2 }}, { 'd': { id: 5 }}]; const sorted = data .sort((a, b) => Object.values(b)[0].id - Object.values(a)[0].id) .map(x => Object.keys(x)[0]); console.log(sorted); 

You can simply do it with javascript by using sort method and mapping over the returned array and returning the keys

 var data = [{ 'a': { id: 4 }}, { 'b': { id: 3 }}, { 'c': { id: 2 }}, { 'd': { id: 5 }}] const res = data.sort((a, b) => Object.values(b)[0].id - Object.values(a)[0].id).map(obj => Object.keys(obj)[0]); console.log(res); 

Or you can use lodash with orderBy and map methods

  var data = [{ 'a': { id: 4 }}, { 'b': { id: 3 }}, { 'c': { id: 2 }}, { 'd': { id: 5 }}] const res = _.orderBy(data, function(a) { return Object.values(a)[0].id }, ['desc']).map(o => Object.keys(o)[0]) console.log(res); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script> 

You can first sort based on id and than map the key.

 let obj = [{ 'a': { id: 4 }}, { 'b': { id: 3 }}, { 'c': { id: 2 }}, { 'd': { id: 5 }}] let op = obj .sort((a,b) => Object.values(b)[0].id - Object.values(a)[0].id) .map(e => Object.keys(e)[0]) console.log(op) 

This is a lodash/fp version of jo_va's solution .

Use _.flow() to create a function that maps each object to a [key, { id }] pair. Sort with _.orderBy() according to id . Iterate with _.map() and dxtract the _.head() (the key):

 const { flow, flatMap, toPairs, orderBy, map, head } = _ const fn = flow( flatMap(toPairs), // convert each object to pair of [key, { id }] orderBy(['[1].id'], ['desc']), // order descending by the id map(head) // extract the original key ) const data = [{ 'a': { id: 4 }}, { 'b': { id: 3 }}, { 'c': { id: 2 }}, { 'd': { id: 5 }}] const result = fn(data) console.log(result) 
 <script src='https://cdn.jsdelivr.net/g/lodash@4(lodash.min.js+lodash.fp.min.js)'></script> 

 const data = [{ a: { id: 4 }}, { b: { id: 3 }}, { c: { id: 2 }}, { d: { id: 5 }}]; data.sort((a, b) => Object.values(b)[0].id - Object.values(a)[0].id); console.log(data); 

The above snippet shows how to do it with Array.sort. Lodash should work similarly.

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