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

// 戻り値: (配列) // 4ggh2,4gghdd2,4gghfg2,7ggh9,9tggfg2,ap1,ap4,ap12

  1. この例では、最初に配列全体を調べ、各項目を新しい 2 項目配列に設定します。新しい配列の最初の項目は、一致した数値と文字列の配列で、2 番目は元の値です。

あなたの例では、array[5]= '9tggfg2' は array[5]= [['9', 'tggfg', '2'], '9tggfg2']] になります。このように、reg exp、match、および toLowerCase 操作は、並べ替えで 2 つの項目が比較されるたびにではなく、項目ごとに 1 回だけ実行されます。

  1. 配列が準備された後、並べ替え関数が適用されます。この関数は、アイテムが両方とも英文字列である場合はアルファベット順に比較し、両方が数値文字列である場合は数値で比較します。数値文字列は、英字文字列の前 (より小さい) に並べ替えます。

  2. 並べ替えの後、配列は再び処理され、今度は各項目が元の値にリセットされます。

並べ替え前と並べ替え後の部分がなくても同じロジックを使用できますが、項目が 3 つ以上ある場合は時間がかかります。

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 に答える