1

这是我的 JavaScript 代码,用于以字母数字方式对数据进行排序:

var reA = /[^a-zA-Z]/g;
var reN = /[^0-9]/g;
function sortAlphaNum(a,b) {
    var aA = a.replace(reA, "");
    var bA = b.replace(reA, "");
    if(aA === bA) {
        var aN = parseInt(a.replace(reN, ""), 10);
        var bN = parseInt(b.replace(reN, ""), 10);
        return aN === bN ? 0 : aN > bN ? 1 : -1;
    } else {
        return aA > bA ? 1 : -1;
    }
}

我的输入数据:

["ap1", "ap4", "ap12","4ggh2","7ggh9","9tggfg2","4gghdd2","4gghfg2"]

排序后应该是这样的:

4ggh2,4hghdd2,4kghfg2,7ggh9,9tggfg2,ap1,ap4,ap12 

这没有发生,你能帮我解决这个问题吗?

function sortAlphaNum(a, b) { 
    var x = a.split("/"); 
    var y = b.split("/"); 
    x = x[x.length-1].replace(/\\\s/g," ").split(/(\d )/); 
    y = y[y.length-1].replace(/\\\s/g," ").split(/(\d )/);  
    for (var i in x) { 
        if (x[i] && !y[i] || isFinite(x[i]) && !isFinite(y[i])) { 
            return -1; 
        } else if (!x[i] && y[i] || !isFinite(y[i]) && isFinite(y[i])) { 
            return 1; 
        } else if (!isFinite(x[i]) && !isFinite(y[i])) { 
            x[i] = x[i].toLowerCase(); 
            y[i] = y[i].toLowerCase(); 
            if (x[i] < y[i]) return -1; 
            if (x[i] > y[i]) return 1; 
        } else { 
            x[i] = parseFloat(x[i]); 
            y[i] = parseFloat(y[i]); 
            if (x[i] < y[i]) return -1; 
            if (x[i] > y[i]) return 1; 
        } 
    } 
    return 0; 
}
alert(["ap1", "ap4", "ap12","4ggh2","7ggh9","9tggfg2","4hghdd2","4kghfg2"].sort(sortAlphaNum));
4

2 回答 2

1

此示例向 Array 原型添加一个方法,

但如果您愿意,它可以写成一个独立的函数,将要排序的数组作为参数传递。

Array.prototype.naturalSort= function(index){
    var T= this, L= T.length, i, who, next, 
    isi= typeof index== 'number', 
    rx=/(\.\d+)|(\d+(\.\d+)?)|([^\d.]+)|(\.\D+)|(\.$)/g;
    function nSort(aa, bb){
        var a= aa[0], b= bb[0], a1, b1, i= 0, n, L= a.length;
        while(i<L){
            if(!b[i]) return 1;
            a1= a[i];
            b1= b[i++];
            if(a1!== b1){
                n= a1-b1;
                if(!isNaN(n)) return n;
                return a1>b1? 1:-1;
            }
        }
        return b[i]? -1:0;
    }
    for(i= 0; i<L; i++){
        who= T[i];
        next= isi? T[i][index] || '':who;
        T[i]= [String(next).toLowerCase().match(rx), who];
    }
    T.sort(nSort);
    for(i= 0; i<L; i++){
        T[i]= T[i][1];
    }
    return this;
}
var A= ["ap1","ap4","ap12","4ggh2","7ggh9","9tggfg2","4gghdd2","4gghfg2"];

A.naturalSort();

// 返回值: (Array) // 4ggh2,4gghdd2,4gghfg2,7ggh9,9tggfg2,ap1,ap4,ap12

  1. 该示例首先遍历整个数组并将每个项目设置为一个新的两项数组 - 新数组的第一项是匹配的数字和字符串数组,第二项是原始值。

在您的示例中,array[5]= '9tggfg2' 变为 array[5]= [['9', 'tggfg', '2'], '9tggfg2']]。这样,reg exp、match 和 toLowerCase 操作只对每个项目执行一次,而不是每次排序比较两个项目时。

  1. 准备好数组后,应用排序函数,如果它们都是字母字符串,则按字母顺序比较项目,如果它们都是数字字符串,则按数字比较。数字字符串在(小于)字母字符串之前排序。

  2. 排序后,再次处理数组,这次将每个项目重置为其原始值。

您可以使用相同的逻辑而无需预排序和后排序部分,但如果您有超过三个项目,则需要更长的时间:

function natSort(as, bs){
    var a, b, a1, b1, i= 0, n, L, 
    rx=/(\.\d+)|(\d+(\.\d+)?)|([^\d.]+)|(\.\D+)|(\.$)/g;
    a= String(as).toLowerCase().match(rx);
    b= String(bs).toLowerCase().match(rx);
    if(as=== bs) return 0;
    L= a.length;
    while(i<L){
        if(!b[i]) return 1;
        a1= a[i], 
        b1= b[i++];
        if(a1!== b1){
            n= a1-b1;
            if(!isNaN(n)) return n;
            return a1>b1? 1:-1;
        }
    }
    return b[i]? -1:0;
}
   ["ap1", "ap4", "ap12", "4ggh2", "7ggh9", 
"9tggfg2", "4gghdd2", "4gghfg2"].sort(natSort);

返回值:(数组) 4ggh2,4gghdd2,4gghfg2,7ggh9,9tggfg2,ap1,ap4,ap12

于 2013-06-05T12:52:44.090 回答
0

尝试:

var input = ["ap1", "ap4", "ap12","4ggh2","7ggh9","9tggfg2","4gghdd2","4gghfg2"];
input.sort();

查看演示:http: //jsfiddle.net/xmkVr/

于 2013-06-05T11:44:04.120 回答