使用 lodash/Javascript 对数字数组进行排序

Sort number array using lodash/Javascript

我有一个字符串数组如下。

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

我想要如下所示的预期输出。

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

我尝试了下面的代码,但没有给出正确的结果。

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

因此,您需要用于数字和符号的比较器。

一般概念:
您可以这样定义符号优先级:

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

其中 key 是符号,value 是我们将在比较器中使用的符号权重('n' 表示“无符号”)。

然后我们将数组元素拆分为数字和符号,在比较器函数中并分别进行比较:

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

完整解:

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

您应该尝试将字符串转换为十进制数,然后进行比较。 例如,如果将“2+”转换为 1.9,将“2-”转换为 2.1,则可以将值作为数字进行比较。

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

function convertToNumber(text) {
    const offset = text.endsWith("+") ? -0.1 : text.endsWith("-") ? 0.1 : 0;
    if (text.endsWith("+") || text.endsWith("-")) {
        text = text.substring(0, text.length - 1);
    }
    return parseFloat(text) + offset;
}

const sorted = arr.sort((a, b) => {
    return convertToNumber(a) > convertToNumber(b);
});
console.log("Sorted: ", sorted);

使用正则表达式单词边界拆分每个字符串。使用解构得到字符串形式的数字(anbn)和符号(asbs)。如果符号是 undefined 使用逗号作为回退,因为逗号在 ascii table.

中位于 +- 之间

return 值应该是 an - bn (auto-casted 数字的差),如果是 0 则使用 bs?.localeCompare(as) 排序签名。

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

const getNumAndSign = str => str.split(/\b/)

const sorted = arr.sort((a, b) => {
  const [an, as = ','] = getNumAndSign(a)
  const [bn, bs = ','] = getNumAndSign(b)
  
  return +an - +bn || bs?.localeCompare(as)
})

console.log(sorted);