Home > Software design >  case sensitive sorting in javascript, where all capital letters come before all lowercase letters
case sensitive sorting in javascript, where all capital letters come before all lowercase letters

Time:01-01

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

  • Related