Search code examples
javascriptunderscore.jslodash

How to use lodash's _sortBy() to alphabetically sort this list with a custom requirement?


I have the following array of objects:

const myList = [
  { id: 1, title: '[A] Animal Bite - F - Not Pregnant' },
  { id: 2, title: '[P] Sinus Pain - M' },
  { id: 3, title: '[A] Animal Bite - F - Pregnant' },
  { id: 4, title: 'Check up male' },
  { id: 5, title: '[A] Animal Bite - M' },
  { id: 6, title: 'Duration' },
  { id: 7, title: '[P] Skin Injury - F - Not Pregnant' },
  { id: 8, title: '[P] Skin Injury - M' },
  { id: 9, title: 'Emergency Screening' }
]

After doing:

_.sortBy(myList, 'title');

I get:

Check up male
Duration
Emergency Screening
[A] Animal Bite - F - Not Pregnant
[A] Animal Bite - F - Pregnant
[A] Animal Bite - M
[P] Sinus Pain - M
[P] Skin Injury - F - Not Pregnant
[P] Skin Injury - M

It looks good except I want the items without [A] or [P] to be at the bottom instead of the top. So like this instead:

[A] Animal Bite - F - Not Pregnant
[A] Animal Bite - F - Pregnant
[A] Animal Bite - M
[P] Sinus Pain - M
[P] Skin Injury - F - Not Pregnant
[P] Skin Injury - M
Check up male
Duration
Emergency Screening

How to achieve this?


Solution

  • Use localeCompare with numeric: false option in the sort function:

    const list = [ { id: 1, title: '[A] Animal Bite - F - Not Pregnant' }, { id: 2, title: '[P] Sinus Pain - M' }, { id: 3, title: '[A] Animal Bite - F - Pregnant' }, { id: 4, title: 'Check up male' }, { id: 5, title: '[A] Animal Bite - M' }, { id: 6, title: 'Duration' }, { id: 7, title: '[P] Skin Injury - F - Not Pregnant' }, { id: 8, title: '[P] Skin Injury - M' }, { id: 9, title: 'Emergency Screening' } ] 
    
    const r = list.sort((a,b) => a.title.localeCompare(b.title, 0, {numeric: false}))
    
    console.log(r)

    Another way you can also get the same result is via the {caseFirst: lower'} option parameter as noted (and explained) by @xehpuk asnwer:

    const list = [ { id: 1, title: '[A] Animal Bite - F - Not Pregnant' }, { id: 2, title: '[P] Sinus Pain - M' }, { id: 3, title: '[A] Animal Bite - F - Pregnant' }, { id: 4, title: 'Check up male' }, { id: 5, title: '[A] Animal Bite - M' }, { id: 6, title: 'Duration' }, { id: 7, title: '[P] Skin Injury - F - Not Pregnant' }, { id: 8, title: '[P] Skin Injury - M' }, { id: 9, title: 'Emergency Screening' } ] 
    
    const r = list.sort((a,b) => a.title.localeCompare(b.title, 0, {caseFirst: 'lower'}))
    
    console.log(r)

    You also do not need lodash for this if ES6 is an option.