简体   繁体   English

使用JavaScript对多维数组进行排序:整数

[英]Sorting Multidimensional Array with Javascript: Integers

I have a 2D array called "results." 我有一个2D数组,称为“结果”。 Each "row" array in results contains both string and integer values. 结果中的每个“行”数组都包含字符串和整数值。 I'm using this script to sort the array by any "column" on an onclick event: 我正在使用此脚本按onclick事件上的任何“列”对数组进行排序:

function sort_array(results, column, direction) {
var sorted_results = results.sort(value);
function value(a,b) {
    a = a[column];
    b = b[column];
    return a == b ? 0 : (a < b ? -1*direction : 1*direction)
    }
}

This works fine for the columns with strings. 这对于带有字符串的列很好用。 But it treats the columns of integers like strings instead of numbers. 但是它将整数列视为字符串而不是数字。 For example, the values 15, 1000, 200, 97 would be sorted 1000, 15, 200, 97 if "ascending" or 97, 200, 15, 1000 "descending." 例如,值15、1000、200、97如果“升序”将排序为1000、15、200、97,或者将97、200、15、1000“降序”排序。

I've double-checked the typeof the integer values, and the script knows they're numbers. 我仔细检查所有的typeof整数值,并且脚本知道他们的数字。 How can I get it to treat them as such? 我该如何对待他们呢?

Make the types of a and b be part of the comparison that decides what your value function returns. 使a和b的类型成为确定value函数返回value的比较的一部分。 In the process you'll have to decide how to sort integers relative to strings. 在此过程中,您必须决定如何相对于字符串对整数排序。

Alternately you can have a comparison function that takes the values, and does a substitution to replace every string of digits with a string of digits of fixed length, with leading zeros, and then does string comparisons. 或者,您可以具有一个比较函数,该函数接受这些值,并执行替换操作,以固定长度的数字字符串替换每个数字字符串,并以前导零代替,然后进行字符串比较。 A benefit of this approach is that you wind up sorting things like "a2", "a9", "a10", etc. Which people generally like. 这种方法的好处是您可以对人们通常喜欢的东西进行排序,例如“ a2”,“ a9”,“ a10”等。

Are you sure they're numbers? 您确定他们是数字吗? How did you check? 你怎么检查的? Try this modification to force them to be numbers just in case: 尝试进行此修改以强制将它们设为数字,以防万一:

if (isNumberColumn(column)) {
    a = +a;
    b = +b;
}

I think that you're going to have to make a preliminary pass over the values in a column before sorting. 我认为您将需要在排序之前对列中的值进行初步传递。 Why? 为什么? Well you need to know in advance (before sorting, that is) whether all the values can be treated as numbers. 那么,您需要事先知道(在排序之前)是否所有值都可以视为数字。 If they can, then the "value" function can convert them. 如果可以,则“值”功能可以转换它们。 Otherwise, it should sort them as strings. 否则,应将它们按字符串排序。

you could try to make your own comparison function, one that suit your needs. 您可以尝试建立自己的比较功能,以满足您的需求。 You could define your own way of comparing strings with ints. 您可以定义自己的将字符串与整数进行比较的方式。 ex : 例如:

function getDirection(a,b){
    if(typeof(a) == typeof(b))
        return a == b ? 0 : (a>b?1:-1);
    a+="";b+="";
    if(a[0] == '-')
        {
            if(b[0] != '-')
                return 1;
        }
    else 
        if(b[0] != '-')
            return -1;
     return a[0] == b[0] ? 0 : (a[0]>b[0]?1:-1);
}

Hope it helps. 希望能帮助到你。

Firstly: sort is a mutator, which means sorting happens in place. 首先:sort是一个变量,这意味着排序发生在适当的位置。 So to avoid unintended consequeces, i'd change 因此,为了避免意外征服,我会更改

var sorted_results = results.sort(value);

to

var sorted_results = results.slice(0).sort(value);

unless of course you wish it sorted in place, but then what do you need the sorted_results variable for? 除非您当然希望将其排序,但是您需要sorted_results变量做什么?

As for the sorting itself - the integer sorting seems to work just fine for me, the problem is really the strings in the mixed integer and string scenario, as seen in his example: http://jsfiddle.net/QJ5fM/ , where it sort the following arrays quite differently: 至于排序本身-整数排序对我来说似乎很好,问题实际上是混合整数和字符串方案中的字符串,如他的示例所示: http : //jsfiddle.net/QJ5fM/ ,对以下数组进行排序有很大不同:

[[16],[131],['aa'],['0hey'],[176],[100],['hey'],[1],[12]];
[['aa'],[16],[131],['0hey'],[176],[100],['hey'],[1],[12]];
[['aa'],['0hey'],[16],[131],[176],[100],['hey'],[1],[12]];

giving the following result in chrome 9: 在chrome 9中给出以下结果:

1,12,0hey,aa,hey,16,100,131,176
1,12,0hey,16,100,131,176,aa,hey
1,12,16,100,131,176,0hey,aa,hey

the following in firefox 3.6: 在Firefox 3.6中的以下内容:

1,12,0hey,aa,hey,16,100,131,176
1,12,0hey,hey,16,100,131,176,aa
1,12,hey,16,100,131,176,0hey,aa

and the following in ie8: 以及ie8中的以下内容:

0hey,aa,hey,1,12,16,100,131,176
0hey,aa,hey,1,12,16,100,131,176
0hey,aa,hey,1,12,16,100,131,176

As a surprise here, it seems ie8 has the only sane, or at least consistent, implementation :P 令人惊讶的是,ie8似乎是唯一明智的,或者至少是一致的实现:P

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM