如何按字典顺序和数字顺序对一组数字进行排序

How to sort set of numbers both lexicographically and numerically?

本文关键字:数字 顺序 一组 排序 字典 何按      更新时间:2023-09-26

我目前有一组字符串,它们都是数字和带有+或-的数字。例如:

1、1+、1-、2、2+、2-、10

当我使用JavaScript的排序函数排序时给出:

1、1+、1-、10、2、2+、2-

按字典顺序排列,但不按数字顺序排列。是否有一种方法来排序,以便数字以正确的方式出现(第一个列表)?我使用ExtJS商店,所以答案作为一个商店排序器是首选,但纯javascript也很好。谢谢?

编辑:这不仅仅是排序数字。

您可以使用如下自定义排序函数:

var numbers = ['1', '1-', '1+', '2', '2+', '2-', '10'];
numbers.sort(function (a, b){
    var _a = parseFloat(a), // If the values are integers only, parseInt will do too
        _b = parseFloat(b);
    if (_a - _b === 0) {
    	return (a > b) ? 1 : -1;
    } else {
    	return _a - _b;
    }
});
console.log(numbers);

函数检查数值是否相等,如果相等,则返回字典顺序对字符后缀进行排序。如果在等大小写中没有后缀,则无论以何种顺序返回数字。如果只有一个操作数有后缀,则裸数返回负。如果数值不相等,则该函数简单地返回三态,即a - b,它将被求值为negative, 0, positive中的一个。或者实际上是"双状态",因为我们已经处理了0的情况。


更通用的解

上面的代码只是两个不同的单字符后缀的特例。如果后缀更复杂,这里有一个更通用的代码来按数字和后缀排序:

var numbers = ['1', '1-r', '1+q', '1', '2', '2+q', '2-r', '10'];
function suffixSort (suff, asc) {
    asc = 2 * +(!!asc) - 1; // Convert boolean to -1 or 1
    return function (a, b) {
        var _a = parseFloat(a), // Extract the number value
            _b = parseFloat(b),
            aSI = -(a.length - _a.toString().length), // Get the index of suffix start
            bSI = -(b.length - _b.toString().length);
        // Equal number values, sort by suffixes
        if (_a === _b) {
            return (suff.indexOf(a.substr(aSI)) > suff.indexOf(b.substr(bSI))) ? 1 : -1;
        }
        // Inequal number values, sort by numbers
        return asc * (_a - _b);
    }
}
// suffixSort arguments
//   suff: An array of the suffix strings to sort, ordered in the desired sorting order
//   asc:  true = ascending, false = descending. Optional, defaults to descending sort
numbers.sort(suffixSort(['+q', '-r'], true));
console.log(numbers);

这个想法是将后缀存储到一个数组中,当需要后缀排序时,函数比较后缀的数组索引,而不是后缀本身。

suffixSort还允许您决定排序方向。选择的排序方向对后缀排序没有影响,它们总是按照它们在suff数组中出现的顺序返回。

这些值几乎是整数,因此根据praseInt比较它们将几乎让您到达那里。唯一缺少的是对具有相同整数部分的值的特殊处理,其中x-应该先出现,然后是x,最后是x+:

function specialChar(s) {
    c = s.substr(-1);
    if (c == '+') {
        return 1;
    }
    if (c == '-') {
      return -1;
    }
    return 0;
}
function numCompare(a, b) {
    aNum = parseInt(a);
    bNum = parseInt(b);
    cmp = aNum - bNum;
    if (cmp != 0) {
        return cmp;
    }
    // Integer parts are equal - compare the special char at the end
    return specialChar(a) - specialChar(b);
}
arr = ['1' , '1+', '1-', '2', '2+', '2-', '10'];
arr.sort(numCompare);
  var result=[]; 
        result=array.map(function(n){
          if(typeof n==='number') return n;
            if(n[n.length-1]=='+'){
              return parseInt(n.substring(0,n.length-1))
              }
            else if(n[n.length-1]=='-'){
               return 0-parseInt(n.substring(0,n.length-1))
               }
            });
 result.sort(function(a,b){return a-b})

您可以使用Array#sort并将元素分成数字和其他部分,然后返回差值或顺序的差值。

var array = ['10', '2', '2+', '2-', '1', '1+', '1-'];
array.sort(function (a, b) {
    var r = /'d+|'D+/g,
        aa = a.match(r),
        bb = b.match(r),
        order = { '+': 1, '-': 2 };
    return aa[0] - bb[0] || (order[aa[1]] || 0) - (order[bb[1]] || 0);
});
console.log(array);

如果只有三种可能的状态的一个数字,和美国订单number, number+, number美国可以重新创建一个数组表示的数字,把独特的数字从数组,从最小到最大,连接空字符串或算术操作符所需的数量,然后将值数组,.toString()可以用来查看逗号分隔字符串表示数组内的排序值

var str = `314+, 1-, 7+, 1, 1-, 271-, 10-
          , 10+, 271, 271+, 314-, 314
          , 10, 2-, 2, 2+, 7-, 7`;
for (var [nums, order, res, num] = [str.match(/'d+/g), ["", "+", "-"], [], null]
     ; nums.length
     ; num = Math.min.apply(Math, nums)
       , res = [...res, ...order.map(op => num + op)]
       , nums = nums.filter(n => n != num)
    );
console.log(res.toString() + "'n", res);

假设您只是想扔掉符号,那么您可以使用parseInt和array# sort来获得数字顺序。

var data = ['1' , '1+', '1-', '2', '2+', '2-', '10'];
var sortedData = data.sort(function(a,b){return parseInt(a)-parseInt(b);});