Nidhi Dadiya
Nidhi Dadiya

Reputation: 839

Sorting first by text then by number on alpha numeric strings

I have an array like this

["1","0K","11",1,"KE","PQ",5,"5"]

where i want it to sort first by text then by number like below

["KE","PQ","0K","1",1,5,"5","11"]

I used local compare but it didn't seem to be working.

function desc(a,b){
  //below is the code that needs improvement
  return b.toString().localeCompare(a, undefined, {
    numeric: true,
    sensitivity: "base",
  });
}

function sort(order) {
  return order === "desc"
    ? (a, b) => desc(a, b)
    : (a, b) => -desc(a, b);
}

function stableSort(array, cmp){
  const stabilizedThis = array.map((el, index) => [el, index]);
  stabilizedThis.sort((a, b) => {
    const order = cmp(a[0], b[0]);
    if (order !== 0) return order;
    return (a[1]) - (b[1]);
  });
  return stabilizedThis.map((el) => el[0]);
}

var arr = ["1","0K","11",1,"KE","PQ",5,"5"];
console.log(stableSort(arr, sort("asc")))

Upvotes: 1

Views: 902

Answers (3)

axtck
axtck

Reputation: 3965

You could write filter methods to get the strings containing numbers, remove the entries, get numbers and strings separately from rest and then sort them in the way you like.

const data = ["1","0K","11",1,"KE","PQ",5,"5"];

const stringsWithNumbers = data.filter(x => /\d+[a-zA-Z]/.test(x));

const rest = data.filter(x => !stringsWithNumbers.includes(x));

const numbers = rest.filter((x) => parseInt(x, 10));
const words = rest.filter((x) => !parseInt(x, 10));

const result = [
  ...words.sort((a, b) => a.localeCompare(b)), 
  ...stringsWithNumbers.concat(numbers).sort((a, b) => parseInt(a) - parseInt(b)),
];

console.log(result);

Upvotes: 1

rivercity
rivercity

Reputation: 364

    var arr = ["1","OK","11",1,"KE","PQ",5,"5"]
    var wordArr = []
    var numArr = []
    arr.forEach((el) => {
        if(Number(el)){
            numArr.push(el)
        } else {
            wordArr.push(el)
        }
    });
    wordArr.sort()
    numArr.sort((a, b) => a - b)
    arr = wordArr.concat(numArr)
    console.log(arr)

Upvotes: 1

Majed Badawi
Majed Badawi

Reputation: 28414

const sort = (arr = []) => {
  const nonAlpha = /[^a-zA-Z]/g, nonNum = /[^0-9]/g;
  return arr.sort((a, b) => {
    const aStr = String(a), bStr = String(b);
    const aAlpha = aStr.replace(nonAlpha, ""), bAlpha = bStr.replace(nonAlpha, "");
    const alphaCompare = bAlpha.localeCompare(aAlpha);
    if(alphaCompare) return alphaCompare;
    const aNum = +aStr.replace(nonNum, ""), bNum = +bStr.replace(nonNum, "");
    return aNum - bNum;
  });
}

console.log( sort(["1","0K","11",1,"KE","PQ",5,"5"]) );

Upvotes: 1

Related Questions