0

I have a an object. I am able to sort the items by using lodash's _.orderBy(). However, in one of the scenario I have to sort by subject, which is an array of objects. Items inside the subject array are already sorted based on the name.

As subject is an array of the objects, I need to consider the first item for sorting.

[
  {
    "id": "1",
    "name": "peter",
    "subject": [
      {
        "id": "1",
        "name": "maths"
      },
      {
        "id": "2",
        "name": "social"
      }
    ]
  },
  {
    "id": "2",
    "name": "david",
    "subject": [
      {
        "id": "2",
        "name": "physics"
      },
      {
        "id": "3",
        "name": "science"
      }
    ]
  },
  {
    "id": "3",
    "name": "Justin",
    "subject": [
    ]
  }
]

3 Answers 3

1

You can use _.get() to extract the name (or id) of the 1st item in subjects. If no item exists, _.get() will return undefined, which can be replaced with a default value. In this case, we don't want to use an empty string as a default value, since the order would change. Instead I'm checking if the value is a string, if it is I use lower case on it, if not I return it as is.

const arr = [{"id":"1","name":"peter","subject":[{"id":"1","name":"maths"},{"id":"2","name":"social"}]},{"id":"2","name":"david","subject":[{"id":"2","name":"physics"},{"id":"3","name":"science"}]},{"id":"3","name":"Justin","subject":[]}]

const result = _.orderBy(arr, o => {
  const name = _.get(o, 'subject[0].name')
  
  return _.isString(name) ? name.toLowerCase() : name
})

console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for the code snippet. It worked great. But I always use .tolowercase() in my orderBy just to make sure it is not case sensitive. So when I apply .tolowercase to above the code, I am getting an error because one of the item doesn't have any subjects. const result = _.orderBy(arr, o => _.get(o, 'subject[0].name').toLowercase())
See update. Although we can use _.get() default value and set an empty string, this will change the sort order. The solution is to check if the name is a string, if it does set it to lower case, and if not return it as is.
0

Use _.sortBy with a comparison/sorting function argument. Your function itself can look into the receiving arguments subject key (I think its the subject you want to compare?)

Comments

0

Since you have the question also tagged with ES6 here is an JS only solution via Array.sort:

let arr = [ { "id": "1", "name": "peter", "subject": [ { "id": "1", "name": "maths" }, { "id": "2", "name": "social" } ] }, { "id": "2", "name": "david", "subject": [ { "id": "2", "name": "physics" }, { "id": "3", "name": "science" } ] }, { "id": "3", "name": "Justin", "subject": [] }, ] 

const result = arr.sort((a,b) => 
  a.subject.length && b.subject.length 
   ? a.subject[0].name.localeCompare(b.subject[0].name) 
   : a.subject.length ? -1 : 1)

console.log(result)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.