簡體   English   中英

使用自定義排序對JavaScript字符串數組進行排序,以在第一個字符中標點

[英]Sort JavaScript array of strings with custom sorting for punctuation in first character

我在JavaScript中有一個字符串數組:

var nick = ["~xxx", "@blue", "&demo", "+voice", "%yyy",
    "nick1", "Nick2", "webmaster"];

我想對這些字符串進行排序,以便結果按此順序排列:

~xxx &demo @blue %yyy +voice nick1 Nick2 webmaster

我該怎么做?

乍一看似乎有點棘手。 但是,這是一種實現方法,假設列出的特殊字符是您關心的唯一字符:

var separator = '\uFFFF';

var prefixes = {
    '~': '1',
    '&': '2',
    '@': '3',
    '%': '4',
    '+': '5'
};

function specialsort( array ) {
    var prefixed = array.map( function( value ) {
        var prefix = prefixes[ value.charAt(0) ] || '9';
        return prefix +
            value.toLowerCase() +
            separator + value;
    });
    prefixed.sort();
    return prefixed.map( function( value ) {
        return value.split(separator)[1];
    });
}

var nicks = [ "~xxx", "@blue", "&demo", "+voice", "%yyy", "nick1", "Nick2", "webmaster" ];

var sorted = specialsort( nicks );
console.log( sorted );

該代碼通過使用格式如下的字符串創建一個新數組來工作:

  1. 第一個字符是特殊字符的1-5位數字,或在每個字符串開頭找到的任何其他字符的9位數字。 (您可以使用'01','02'等將其擴展為兩位數,而對於其他字符則使用'99'。)
  2. 接下來是小寫的字符串。
  3. 然后使用一個非常大的值( \￿ )的Unicode字符作為分隔符。
  4. 最后是原始字符串。

然后可以直接對這些字符串的數組進行排序,並通過在該分隔符上拆分字符串並使用分隔符后面的部分(原始字符串)將結果轉換為新數組。

或者,使用排序回調函數的方法稍微簡單一些:

var prefixes = {
    '~': '1',
    '&': '2',
    '@': '3',
    '%': '4',
    '+': '5'
};

function specialsort( array ) {
    return array.sort( function( a, b ) {
        a = ( prefixes[ a.charAt(0) ] || '9' ) + a.toLowerCase();
        b = ( prefixes[ b.charAt(0) ] || '9' ) + b.toLowerCase();
        return a < b ? -1 : a > b ? 1 : 0;
    });
}

var nicks = [ "~xxx", "@blue", "&demo", "+voice", "%yyy", "nick1", "Nick2", "webmaster" ];

var sorted = specialsort( nicks );
console.log( sorted );

對於冗長的數組,我傾向於采用第一種方法-制作修改后的數組並對其進行排序-因為它比使用排序回調要快。 但是sort回調有點簡單,對於這種大小的數組,它沒有錯。

排序回調方法確實比修改后的數組還有另一個優點:它不依賴於那種有點亂七八糟的分隔符。

無論哪種方式,輸出為:

["~xxx", "&demo", "@blue", "%yyy", "+voice", "nick1", "Nick2", "webmaster"]

這是第一個版本小提琴,第二個版本小提琴

您可以使用正則表達式和localeCompare()函數,為不區分大小寫的比較添加兩個小寫字母:

var nick = ["~xxx", "@blue", "&demo", "+voice", "%yyy", "nick1", "Nick2", "webmaster"];
nick.sort(function(a,b){
    return a.toLowerCase().replace(/[^\w\s]/gi, '').localeCompare(b.toLowerCase().replace(/[^\w\s]/gi, ''));
});
console.log(nick); // ["@blue", "&demo", "nick1", "Nick2", "+voice", "webmaster", "~xxx", "%yyy"]

http://jsfiddle.net/4JJVV/

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM