对JavaScript字符串数组进行排序,并在第一个字符中使用自定义排序标点符号

时间:2013-07-06 10:16:38

标签: javascript sorting

我在JavaScript中有一个字符串数组:

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

我想对这些字符串进行排序,结果按此顺序排列:

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

我该怎么做?

2 个答案:

答案 0 :(得分:1)

起初看起来有点棘手。但是这里有一种方法可以做到这一点,假设列出的特殊字符是您唯一关注的字符:

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. 然后是一个非常大的值(\uFFFF)作为分隔符的Unicode字符。
  4. 最后,原始字符串。
  5. 然后可以直接对这些字符串的数组进行排序,并通过拆分该分隔符上的字符串并使用分隔符后面的部分(原始字符串)将结果转换为新数组。

    或者,使用排序回调函数的一种稍微简单的方法:

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

    对于冗长的数组,我倾向于采用第一种方法 - 制作修改后的数组并对其进行排序 - 因为它比使用排序回调更快。但排序回调有点简单,对于这个大小的数组来说没有任何问题。

    排序回调方法确实比修改后的数组有另一个优势:它不依赖于那个稍微有点hacky的分隔符。

    无论哪种方式,输出都是:

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

    这是fiddle for the first versionfiddle for the second version

答案 1 :(得分:0)

你可以使用正则表达式和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/