I need to sort two strings in a way that capital letters come first, even for different letters, for example:
Cat comes before ant
CD comes before Cd
Can I use localCompare to sort like that?
const sortString = (a, b) => String(a).localeCompare(b);
No, you can't (and don't need to) use localeCompare for that. What you describe is just the standard string comparison, which puts letters in alphabetical order and uppercase letters before the lowercase ones!
So all you need to do is
arr.sort((a, b) => +(a>b)||-(b>a))
which for strings is the same as the default fallback comparison function so you can just do
arr.sort()
My function return 1 if first string is greater, -1 if first string is less than and 0 if it is equal second string.
// return value like compare function
const findCompareValue = (flag) => {
if (flag) {
return -1;
} else {
return 1;
}
}
const compareCaseSensitive = (a, b) => {
// find min length just in case two string don't have the same length
const minLen = a.length > b.length ? b.length : a.length;
let i = 0;
const minLowerCaseCharCode = 97;
const maxLowerCaseCharCode = 122;
const minUpperCaseCharCode = 65;
const maxUpperCaseCharCode = 90;
while (true && i !== minLen) {
// get char code
const aCharCode = a[i].charCodeAt();
const bCharCode = b[i].charCodeAt();
// check whether character is uppercase
const isACharUpperCase = minUpperCaseCharCode <= aCharCode && aCharCode <= maxUpperCaseCharCode;
const isBCharUpperCase = minUpperCaseCharCode <= bCharCode && bCharCode <= maxUpperCaseCharCode;
if (isACharUpperCase) {
if (isBCharUpperCase && bCharCode !== aCharCode) {
// two characters are uppercase and different
return findCompareValue(aCharCode < bCharCode);
} else if (aCharCode !== bCharCode) {
// second character is lowercase
return 1;
}
} else {
if (isBCharUpperCase) {
// second string is uppercase
return -1;
} else if (aCharCode !== bCharCode) {
// two characters are lowercase and different
return findCompareValue(aCharCode < bCharCode);
}
}
i += 1;
}
return 0;
}
const a = 'CD';
const b = 'cD';
console.log('result', compareCaseSensitive(a, b));
Can you try this, not sure all the requirements are satisfied or not...
Input: ['Cat', 'March', 'aJan','Feb', 'Feb', 'Dd', 'DD', 'ant', 'cat', 'AMC', 'AMBulance', 'Feb','Cd' , 'CD']
Output: ["AMBulance", "AMC", "CD", "Cat", "Cd", "DD", "Dd", "Feb", "Feb", "Feb", "March", "aJan", "ant", "cat"]
const months = ['Cat', 'March', 'aJan','Feb', 'Feb', 'Dd', 'DD', 'ant', 'cat', 'AMC', 'AMBulance', 'Feb','Cd' , 'CD']
function _sort(a,b) {
const aLenth = a.length
const bLenth = b.length
const aArr = a.match(/^[A-Z]*/g )
const bArr = b.match(/^[A-Z]*/g )
const isCapA = Array.isArray(aArr) && !!aArr[0].length
const isCapB = Array.isArray(bArr) && !!bArr[0].length
const isBothCapital = isCapA && isCapB // then check usual way
const isBothSimple = !isCapA && !isCapB // then check usual way
//console.log(a, b, isBothCapital, aArr.length, bArr.length)
if (isBothCapital || isBothSimple){
if (a === b ) {
return 0
}
if (aArr[0].length === bArr[0].length) {
return a.localeCompare(b);
}
//return a.localeCompare(b);
return aArr[0].length - bArr[0].length ? 1 : -1
}
if (isCapA) {
return -1
}
return 1
}
const _simpSort = (a,b ) => {
return a.localeCompare(b)
}
const capLetters = months.filter(x => x.match(/^[A-Z]/g))
const simpLetters = months.filter(x => x.match(/^[a-z]/g))
const formatted = [...capLetters.sort(_simpSort), ...simpLetters.sort(_simpSort)]
const groupBy = formatted.reduce((acc, i) => {
const isExists = acc[i.charAt(0)]
const ele = typeof isExists !== "undefined" ? isExists : []
const tmp = { [i.charAt(0)]: [i, ...ele] }
return { ...acc, ...tmp}
}, {})
const final = []
for (ele in groupBy) {
const tmpRow = groupBy[ele].sort(_sort)
final.push(tmpRow)
}
console.log(final.join().split(","))