简体   繁体   English

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

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

I have an array of strings in JavaScript: 我在JavaScript中有一个字符串数组:

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

I want to sort those strings so the result is in this order: 我想对这些字符串进行排序,以便结果按此顺序排列:

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

How can I do it? 我该怎么做?

This is a bit trickier that it may seem at first. 乍一看似乎有点棘手。 But here is one way to do it, assuming the special characters listed are the only ones you're concerned with: 但是,这是一种实现方法,假设列出的特殊字符是您关心的唯一字符:

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

The code works by creating a new array with strings formatted like this: 该代码通过使用格式如下的字符串创建一个新数组来工作:

  1. The first character is a digit 1-5 for the special characters or 9 for any other character found at the beginning of each string. 第一个字符是特殊字符的1-5位数字,或在每个字符串开头找到的任何其他字符的9位数字。 (You could extend this to two digits using '01', '02', etc. and '99' for other characters.) (您可以使用'01','02'等将其扩展为两位数,而对于其他字符则使用'99'。)
  2. Next is the string in lowercase. 接下来是小写的字符串。
  3. Then a Unicode character with a very large value ( \￿ ) as a separator. 然后使用一个非常大的值( \￿ )的Unicode字符作为分隔符。
  4. Finally, the original string. 最后是原始字符串。

The array of these strings can then be sorted directly, and the result is converted to a new array by splitting the strings on that separator and using the part after the separator (the original string). 然后可以直接对这些字符串的数组进行排序,并通过在该分隔符上拆分字符串并使用分隔符后面的部分(原始字符串)将结果转换为新数组。

Or, a slightly simpler approach using a sort callback function: 或者,使用排序回调函数的方法稍微简单一些:

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

For lengthy arrays, I tend to go for the first approach—making a modified array and sorting it—because it can be faster than using a sort callback. 对于冗长的数组,我倾向于采用第一种方法-制作修改后的数组并对其进行排序-因为它比使用排序回调要快。 But the sort callback is a bit simpler and there's nothing wrong with it for an array of this size. 但是sort回调有点简单,对于这种大小的数组,它没有错。

The sort callback approach does have one other advantage over the modified array: it doesn't depend on that slightly hacky separator character. 排序回调方法确实比修改后的数组还有另一个优点:它不依赖于那种有点乱七八糟的分隔符。

Either way, the output is: 无论哪种方式,输出为:

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

Here's a fiddle for the first version and a fiddle for the second version . 这是第一个版本小提琴,第二个版本小提琴

You can use regular expression and localeCompare() function, for case insensitive comparation add two lowercases: 您可以使用正则表达式和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/ http://jsfiddle.net/4JJVV/

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

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