javascript - Utför en skiftlägeskänslig strängsortering i TypeScript


Jag har en array som ser ut som

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'},

Jag skulle vilja sortera denna array för att få ett resultat

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

Jag har försökt göra

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

vilket gav mig ett resultat

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

Skillnaden är ordningen på skool och Security. Jag vill att alla mina små bokstäver ska komma först och sedan stora bokstäver. Vad kan jag prova för att uppnå detta?

Svar #1

Vill du sortera i alfabetisk ordning eller efter bokstavsstorlek? Om du sorterar alfabetiskt kan du inte få Security efter skool eftersom e kommer före k alfabetiskt.

Om du vill det -

  • Om första bokstaven i två ord är samma, sortera då den med liten bokstav först utan att ta hänsyn till ytterligare alfabetisk ordning.

I så fall kan du använda följande -

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

I ovanstående kodsnutt, om de första bokstäverna i två ord är samma, kommer de att sorteras baserat på skiftläget på deras första bokstav. I alla andra fall kommer de att sorteras alfabetiskt.

REDIGERA : Enligt kommentarens förslag, för en sorteringsfunktion i TS, bör den returnera -

  • 1 : när a > b,
  • 0 : när a === b och
  • -1 :när a < b.

Så, en mer korrekt (och också läsbar) version har nämnts i svaret.

Hoppas det här hjälper!

Svar #2

Prova detta:

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