Home > Net >  Why does my custom sort() function cannot be accepted in JavaScript?
Why does my custom sort() function cannot be accepted in JavaScript?

Time:02-26

I tried to upgrade the current custom sort function of JavaScript to create a new order of sorting
e.g. (1, 2, 3, 4,..., !@#$%^= , a, A, b, B, c, C)


function getSortOrder(prop) {
    return function (a, b) {
        if (isSpecialChar(a[prop], 0) || isSpecialChar(b[prop], 0)) {
            return sortData(a[prop], b[prop]);
        }
        if (isNumeric(a[prop], 0) == "number" || isNumeric(b[prop], 0) == "number") {
            return getSortNumeric(a[prop], b[prop]);
        }
        if (isLetter(a[prop], 0) || isLetter(b[prop], 0)) {
            return getSortLetter(a[prop], b[prop]);
        }
    };
}


function getSortLetter(a, b) {
    if ((a.charAt(0) === getLowerCase(a, 0)) && (b.charAt(0) === getUpperCase(b, 0))) {
        return sortData(a, b);
    }
    return sortData(a, b);
}
function getSortNumeric(a, b) {
    if (typeof a[prop] == "number") {
        return (a[prop] - b[prop]);
    } else {
        return ((a[prop] < b[prop]) ? -1 : ((a[prop] > b[prop]) ? 1 : 0));
    }
}

function sortData(a, b) {
    if (a.toLowerCase() < b.toLowerCase()) {
        return -1;
    } else if (a.toLowerCase() > b.toLowerCase()) {
        return 1;
    } else {
        return 0;
    }
}

// to check if the data has numeric
function isNumeric(str, index) {
    let x = /^[0-9]$/.test(str.charAt(index));
    console.log(str, x);
    return x;
}

// to determine if the data has neither numeric or letter

function isSpecialChar(str, index) {
    return !isNumeric(str, index) && !isLetter(str, index);
}

// to specify the order of letter e.g. (jane doe, Jane Doe, john doe, John doe)

function isLetter(str, index) {
    return str.charAt(index).length === 1 && str.match(/[a-z]/i);
}
function getLowerCase(str, index) {
    return str.charAt(index).toLowerCase();
}
function getUpperCase(str, index) {
    return str.charAt(index).toUpperCase();
}

expected result of Json Values:

List of Users:

123Admin
321user
!testAdmin
#adminData
jane doe
Jane Smith
john doe
John Doe

Current results of Json Values:
List of Users:

!testAdmin
#adminData
123Admin
321user
Jane Smith
jane doe
john doe

It still follows the Ascii default order of sort.

CodePudding user response:

You could take a brute force approach with an string/object for the wanted order.

This appriach iterate each pair of strings and check any character by getting the order until finding different characters.

const
   chars = ' 0123456789!@#$%^= abcdefghijklmnopqrstuvwxyz',
   order = Object.fromEntries(Array.from(chars, ((c, i) => [c, i   1]))),
   sort = (a, b) => {
       for (let i = 0, l = Math.min(a.length, b.length); i < l; i  ) {
           const r = order[a[i].toLowerCase()] - order[b[i].toLowerCase()];
           if (r) return r;
       }
       return a.length - b.length;
   };
   data = ['abcd', 'abc', 'John Doe', '!testAdmin', '#adminData', '123Admin', '321user', 'Jane Smith', 'jane doe', 'john doe'];

data.sort(sort);

console.log(data);
.as-console-wrapper { max-height: 100% !important; top: 0; }

CodePudding user response:

The approach suggested by Nina Scholz is more concise, but here is what was wrong with your original code:

Your isLetter function does not return the correct result. Using the RegExp.test method as below would fix that:

function isLetter(str, index) {
  return str.charAt(index).length === 1 && /^[a-z]/i.test(str);
}

Your getSortOrder function also does not handle sorting correctly when comparing characters that belong to different groups (special character / number / letter). To fix that, you could change that function to distinguish when the characters are in the same group versus when they are in different groups:

function getSortOrder(a, b) {
  if (isNumeric(a, 0) && isNumeric(b, 0)) return sortData(a, b);
  if (isSpecialChar(a, 0) && isSpecialChar(b, 0)) return sortData(a, b);
  if (isLetter(a, 0) && isLetter(b, 0)) return sortData(a, b);
  if (isNumeric(a, 0)) return -1;
  if (isLetter(a, 0)) return 1;
  if (isSpecialChar(a, 0)) {
    if (isNumeric(b, 0)) return 1;
    return -1;
  }
}

Finally, the sortData function does not distinguish between lower and upper case. It would need to do something like this:

function sortData(a, b) {
    const aLower = a[0].toLowerCase();
    const bLower = b[0].toLowerCase();
    if (aLower === bLower) {
        if (a[0] === aLower && b[0] !== bLower) return -1;
        if (a[0] !== aLower && b[0] === bLower) return 1;
        return 0;
    }
    if (aLower < bLower) return -1;
    if (aLower > bLower) return 1;
    return 0;
}
  • Related