小编典典

排序数组元素(带数字的字符串),自然排序

javascript

我有一个数组

["IL0 Foo", "PI0 Bar", "IL10 Baz", "IL3 Bob says hello"]

并且需要对其进行排序,使其看起来像;

["IL0 Foo", "IL3 Bob says hello", "IL10 Baz", "PI0 Bar"]

我尝试了排序功能;

function compare(a,b) {
  if (a < b)
     return -1;
  if (a > b)
    return 1;
  return 0;
}

但这给出了命令

["IL0 Foo", "IL10 Baz", "IL3 Bob says hello", "PI0 Bar"]

我试图考虑一个正则表达式可以正常工作,但无法解决这个问题。
如果有帮助,格式将始终为2个字母,x个数字,然后是任意数量的字符。


阅读 370

收藏
2020-04-25

共1个答案

小编典典

这称为“自然排序”,可以像这样在JS中实现:

function naturalCompare(a, b) {

    var ax = [], bx = [];



    a.replace(/(\d+)|(\D+)/g, function(_, $1, $2) { ax.push([$1 || Infinity, $2 || ""]) });

    b.replace(/(\d+)|(\D+)/g, function(_, $1, $2) { bx.push([$1 || Infinity, $2 || ""]) });



    while(ax.length && bx.length) {

        var an = ax.shift();

        var bn = bx.shift();

        var nn = (an[0] - bn[0]) || an[1].localeCompare(bn[1]);

        if(nn) return nn;

    }



    return ax.length - bx.length;

}



/////////////////////////



test = [

    "img12.png",

    "img10.png",

    "img2.png",

    "img1.png",

    "img101.png",

    "img101a.png",

    "abc10.jpg",

    "abc10",

    "abc2.jpg",

    "20.jpg",

    "20",

    "abc",

    "abc2",

    ""

];



test.sort(naturalCompare)

document.write("<pre>" + JSON.stringify(test,0,3));

要以相反的顺序排序,只需交换参数即可:

test.sort(function(a, b) { return naturalCompare(b, a) })

或简单地

test = test.sort(naturalCompare).reverse();
2020-04-25