Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sort number array using lodash/Javascript

I have a string array as below.

let arr = ["1", "1+", "1-","2", "2+", "3","3+", "2-", "3-", "4", "10"];

I want the expected output as below.

["1+", "1", "1-", "2+", "2", "2-", "3+", "3", "3-", "4", "10"];

I tried the below code but it is not giving me the correct result.

let arr = ["1", "1+", "1-","2", "2+", "3","3+", "2-", "3-", "4", "10"];
let result = arr.sort((a,b) => { 
  return a.localeCompare(b, undefined, {
      numeric: true,
      sensitivity: 'base',
    });
  });

console.log(result);
like image 869
Ayaz Avatar asked Sep 20 '25 10:09

Ayaz


1 Answers

So, you need comparator for numbers and for signs.

Gerenal concept:
You can define sign priority like this:

const signPriority = {
  '+': 0,
  'n': 1, // n = no sign
  '-': 2,
} 

Where key is sign and value is sign weight we will use in comparator ('n' means "no sign").

Then we will split up array elements to number and sign, in comparator function and comparate them separetely:

arr.sort((a, b) => { 
    // If numbers are different ...
    if (parseInt(a) !== parseInt(b)) {
        // Just compare a numbers 
        return parseInt(a) - parseInt(b);
    } else {
        // If sign matter ...
        // Extract sign from element or define as 'n' if no sign found
        const sign_a = ['+', '-'].includes(a.slice(-1)) ? a.slice(-1) : 'n';
        const sign_b = ['+', '-'].includes(b.slice(-1)) ? b.slice(-1) : 'n';
        // Compare signs using their weight
        return signPriority[sign_a] - signPriority[sign_b];
    } 
})

Full solution:

const signPriority = {
    '+': 0,
    'n': 1,
    '-': 2,
} 

const arr = ["1", "1+", "1-","2", "2+", "3","3+", "2-", "3-", "4", "10"];

const sorted = arr.sort((a, b) => { 
    if (parseInt(a) !== parseInt(b)) {
        return parseInt(a) - parseInt(b);
    } else {
        const sign_a = ['+', '-'].includes(a.slice(-1)) ? a.slice(-1) : 'n';
        const sign_b = ['+', '-'].includes(b.slice(-1)) ? b.slice(-1) : 'n';
        return signPriority[sign_a] - signPriority[sign_b];
    } 
})

console.log(sorted);
like image 150
Xeelley Avatar answered Sep 22 '25 05:09

Xeelley