chink
chink

Reputation: 1653

Performing a case sensitive string sorting in TypeScript

I have an array which looks like

var arr = [{'Id':'1','Value':'Desk'},
     {'Id':'2','Value':'skool'},
     {'Id':'3','Value':'OT'},
     {'Id':'4','Value':'sector'},
     {'Id':'5','Value':'Security'},
     {'Id':'6','Value':'Zebra'},

I would like to sort this array to get a result

[
  { Id: '1', Value: 'Desk' },
  { Id: '3', Value: 'OT' },
  { Id: '4', Value: 'sector' },
  { Id: '2', Value: 'skool' },
  { Id: '5', Value: 'Security' },
  { Id: '6', Value: 'Zebra' }
]

I have tried doing

arr.sort((a,b) => (a.Value.toLocaleLowerCase() > b.Value.toLocaleLowerCase()) ? 1 : ((b.Value.toLocaleLowerCase() > a.Value.toLocaleLowerCase()) ? -1 : 0)); 

which gave me a result

[
  { Id: '1', Value: 'Desk' },
  { Id: '3', Value: 'OT' },
  { Id: '4', Value: 'sector' },
  { Id: '5', Value: 'Security' },
  { Id: '2', Value: 'skool' },
  { Id: '6', Value: 'Zebra' }
]

Difference is the order of skool and Security. I want all my lower case letters to come up first and then upper case letters. What can I try to achieve this?

Upvotes: 3

Views: 2340

Answers (3)

Yosef Tukachinsky
Yosef Tukachinsky

Reputation: 5895

Try this:

var arr = [{'Id':'1','Value':'Desk'},{'Id':'2','Value':'skool'},{'Id':'3','Value':'OT'},{'Id':'4','Value':'sector'},{'Id':'5','Value':'Security'},{'Id':'6','Value':'Zebra'}];
var sort = (a, b) => a > b ? 1 : (a < b ? -1 : 0);
var sorted = arr.sort((a,b) => 
  sort(a.Value[0].toLowerCase(), b.Value[0].toLowerCase()) || 
  -sort(a.Value[0], b.Value[0]) ||
  sort(a.Value, b.Value));
console.log(sorted);

Upvotes: 0

Abhishek Bhagate
Abhishek Bhagate

Reputation: 5786

Do you want to sort by alphabetical order or case wise? If you are sorting alphabetically you can't get Security after skool because alphabetically, e comes before k.

If you want to that -

  • If first letter of two words is same, then sort the lowercase first irrespective of consideration of further alphabetical order.

In that case you could use following -

var arr = [{
    Id: '1',
    Value: 'Desk'
  },
  {
    Id: '3',
    Value: 'OT'
  },
  {
    Id: '4',
    Value: 'sector'
  },
  {
    Id: '2',
    Value: 'skool'
  },
  {
    Id: '5',
    Value: 'Security'
  },
  {
    Id: '6',
    Value: 'Zebra'
  }
];


arr.sort(function(a, b) {
  //if exactly same strings, return 0
  if (a.Value === b.Value)
    return 0;
  //if first case of a and b are unequal return based on case
  if (a.Value.toLocaleLowerCase()[0] === b.Value.toLocaleLowerCase()[0] && a.Value[0] !== b.Value[0])
    return a.Value[0] < b.Value[0] ? 1 : -1;
  //Now return 0 if both are equal in lower case else return 1 or -1 depending on comparison below
  if (a.Value.toLocaleLowerCase() === b.Value.toLocaleLowerCase())
    return 0;
  return a.Value.toLocaleLowerCase() > b.Value.toLocaleLowerCase() ? 1 : -1;

});


//Apparently below code is not the exactly right way to do it, so use the above method
//arr.sort((a, b) => (a.Value.toLocaleLowerCase()[0] === b.Value.toLocaleLowerCase()[0]) ? (a.Value[0] > b.Value.[0]?1:-1) : (a.Value.toLocaleLowerCase() > b.Value.toLocaleLowerCase()?1:-1));

console.log(arr);

In the above snippet, if the first letters of any two words are same, they will be sorted based on the case of their first letter. In all other cases, it will be sorted alphabetically.

EDIT : As per the comment suggestion, for a sort function in TS, it should return -

  • 1 : when a > b,
  • 0 : when a === b and
  • -1 :when a < b.

So, a more correct(as well as readable) version has been mentioned in the answer.

Hope this helps !

Upvotes: 1

AttemptedMastery
AttemptedMastery

Reputation: 768

Just to have in your bag of tricks, if you want to alphabetize all lower case letters first, then follow that up with all capitalized letters, you can use this:

arr.sort(function (a, b) {
    if (a.Value[0] === a.Value[0].toLowerCase() && b.Value[0] === b.Value[0].toLowerCase() ||
        a.Value[0] === a.Value[0].toUpperCase() && b.Value[0] === b.Value[0].toUpperCase()) {
        return a.Value.localeCompare(b.Value);
    }
    if (a.Value[0] === a.Value[0].toLowerCase()) {
        return -1;
    }
    return 1;
});

Here is the output:

[ { Id: '4', Value: 'sector' },
  { Id: '2', Value: 'skool' },
  { Id: '1', Value: 'Desk' },
  { Id: '3', Value: 'OT' },
  { Id: '5', Value: 'Security' },
  { Id: '6', Value: 'Zebra' } ]

Upvotes: 0

Related Questions