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);
CodePudding user response:
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));
CodePudding user response:
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(","))
CodePudding user response:
You're lucky because A-Z char code is smaller than a-z, so we can just use charCode to sort.
The tricky bit is to loop through each character.
const list = ['Cat', 'Cat2', 'ant', 'CD', 'Cd', 'cD', 'Ab', 'zb', 'zC'];
const sortByCharcode = (a, b) => {
if (a.charCodeAt(0) < b.charCodeAt(0)) return -1;
if (a.charCodeAt(0) > b.charCodeAt(0)) return 1;
return 0;
}
const sortFunc = (strA, strB) => {
// Loop through each character.
for (let i = 0; i < strB.length; i ) {
const a = strA[i];
const b = strB[i];
const compareResult = sortByCharcode(a, b); // Compare each index
// If result is -1 or 1, return it, if it's still 0 then move to next character.
if (compareResult !== 0) return compareResult;
}
// If strB.length run out, A comes before B
return 1;
}
const sortedList = list.sort(sortFunc);
console.log(sortedList);