I want to sort an array with strings alphabetically. However, upper case letters should be always before the corresponding lower case letter (example order: A a B b ...).
To archive this, I have tried to use localCompare with caseFirst: "upper" and sensitivity: "case":
const input = ["ADR 2023", "Added Values", "DEMO build", "DEMO Build", "2nd Outlook", "demo award"]
const output = input.sort((a, b) => a.localeCompare(b, "en-US", { caseFirst: "upper", sensitivity: "case" }))
console.log(output)
I would expect the output to be:
["2nd Outlook", "ADR 2023", "Added Values", "DEMO Build", "DEMO build", "demo award"]
Unfortunately, the output is:
["2nd Outlook", "Added Values", "ADR 2023", "demo award", "DEMO Build", "DEMO build"]
How can I get the expected order? In the example, I have used en-US as locale. However, in my real project, it can be any supported locale with a length of five characters.
localeCompare() since it creates Intl.Collator every time - tooooo slow.const input = ["ADR 2023", "Added Values", "DEMO build", "DEMO Build", "2nd Outlook", "demo award"];
const {compare} = Intl.Collator("en-US", { caseFirst: "upper"});
const output = input.sort((a, b) => {
for(let i = 0; i < a.length && i < b.length; i++){
const r = compare(a[i], b[i]);
if(r) return r;
}
if(a.length > b.length) return 1;
if(a.length < b.length) return -1;
return 0;
})
console.log(output)
A string iterator version as suggested by VLAZ:
const input = ["ADR 2023", "Added Values", "DEMO build", "DEMO Build", "2nd Outlook", "demo award"];
const {compare} = Intl.Collator("en-US", { caseFirst: "upper"});
const output = input.sort((a, b) => {
const ia = a[Symbol.iterator](), ib = b[Symbol.iterator]();
while(true){
const ca = ia.next().value, cb = ib.next().value;
if(!ca) return ba ? -1 : 0
if(ca && !cb) return 1;
const r = compare(ca, cb);
if(r) return r;
}
})
console.log(output)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With