Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 排序数组元素(带数字的字符串),自然排序_Javascript_Jquery_Sorting - Fatal编程技术网

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

Javascript 排序数组元素(带数字的字符串),自然排序,javascript,jquery,sorting,Javascript,Jquery,Sorting,我有一个数组像 ["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", "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;
}
我试着想一个可以工作的正则表达式,但我的头脑却无法理解它。

如果有帮助的话,格式将始终是2个字母,x个数字,然后是任意数量的字符。

不漂亮,但请检查前两个字符代码。如果全部相等,则解析并比较数字:

var arr = ["IL0 Foo", "IL10 Baz", "IL3 Bob says hello", "PI0 Bar"];
arr.sort(function (a1, b1) {
    var a = parseInt(a1.match(/\d+/g)[0], 10),
        b = parseInt(b1.match(/\d+/g)[0], 10),
        letterA = a1.charCodeAt(0),
        letterB = b1.charCodeAt(0),
        letterA1 = a1.charCodeAt(1),
        letterB1 = b1.charCodeAt(1);
    if (letterA > letterB) {
        return 1;
    } else if (letterB > letterA) {
        return -1;
    } else {
        if (letterA1 > letterB1) {
            return 1;
        } else if (letterB1 > letterA1) {
            return -1;
        }
        if (a < b) return -1;
        if (a > b) return 1;
        return 0;
    }
});
var-arr=[“IL0-Foo”、“IL10-Baz”、“IL3-Bob打招呼”、“PI0-Bar”];
arr.sort(功能(a1、b1){
var a=parseInt(a1.match(/\d+/g)[0],10),
b=parseInt(b1.match(/\d+/g)[0],10),
字母A=a1.字符代码(0),
字母B=b1.字符编码(0),
字母a1=a1.字符代码(1),
字母b1=b1.字符编码(1);
如果(字母A>字母B){
返回1;
}否则如果(字母B>字母A){
返回-1;
}否则{
如果(字母A1>字母B1){
返回1;
}否则如果(字母B1>字母A1){
返回-1;
}
如果(ab)返回1;
返回0;
}
});
var re=/([a-z]+)(\d+)(.+)/i;
var arr=[“il0foo”、“pi0bar”、“il10baz”、“il3bob说你好”];
变量顺序=arr.sort(函数(a,b){
var ma=a.匹配(re),
mb=b.匹配(re),
a_str=ma[1],
b_str=mb[1],
a_num=parseInt(ma[2],10),
b_num=parseInt(mb[2],10),
a_rem=ma[3],
b_rem=mb[3];
返回a_str>b_str?1:a_strb_num?1:a_numb_rem;
});

您可以执行如下正则表达式以获取字符串的非数字和数字部分:

var s = "foo124bar23";
s.match(/[^\d]+|\d+/g)
返回:
[“foo”、“124”、“bar”、“23”]

然后,在比较函数中,您可以遍历两个字符串的各个部分,逐个比较它们。第一个不匹配部分确定整体比较的结果。对于每个部件,检查部件是否以数字开头,如果是,则在进行比较之前将其解析为数字。

这称为“自然排序”,可以在JS中实现,如下所示:

函数自然比较(a,b){
var ax=[],bx=[];
a、 替换(/(\d+)(\d+)/g,函数(u,$1,$2){ax.push([$1 | | |无穷,$2 | |”“]);
b、 替换(/(\d+)|(\d+)/g,函数(_,$1,$2){bx.push([$1 | |无穷大,$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]);
如果(nn)返回nn;
}
返回ax.length-bx.length;
}
/////////////////////////
测试=[
“img12.png”,
“img10.png”,
“img2.png”,
“img1.png”,
“img101.png”,
“img101a.png”,
“abc10.jpg”,
“abc10”,
“abc2.jpg”,
“20.jpg”,
"20",
“abc”,
“abc2”,
""
];
测试.排序(自然比较)
document.write(“+JSON.stringify(test,0,3))再添加一个备选方案(为什么不添加):

var ary = ["IL0 Foo", "PI0 Bar", "IL10 Hello", "IL10 Baz", "IL3 Bob says hello"];

// break out the three components in to an array
// "IL10 Bar" => ['IL', 10, 'Bar']
function getParts(i){
    i = i || '';
    var parts = i.match(/^([a-z]+)([0-9]+)(\s.*)$/i);
    if (parts){
        return [
            parts[1],
            parseInt(parts[2], 10),
            parts[3]
        ];
    }
    return []; // erroneous
}
ary.sort(function(a,b){
    // grab the parts
    var _a = getParts(a),
        _b = getParts(b);

    // trouble parsing (both fail = no shift, otherwise
    // move the troubles element to end of the array)
    if(_a.length == 0 && _b.length == 0) return 0;
    if(_a.length == 0) return -1;
    if(_b.length == 0) return 1;

    // Compare letter portion
    if (_a[0] < _b[0]) return -1;
    if (_a[0] > _b[0]) return 1;
    // letters are equal, continue...

    // compare number portion
    if (_a[1] < _b[1]) return -1;
    if (_a[1] > _b[1]) return 1;
    // numbers are equal, continue...

    // compare remaining string
    if (_a[2] < _b[2]) return -1;
    if (_a[2] > _b[2]) return 1;
    // strings are equal, continue...

    // exact match
    return 0;
});
var-ari=[“il0foo”、“pi0bar”、“il10hello”、“il10baz”、“il3bob说Hello”];
//将三个组件拆分为一个数组
//“IL10 Bar”=>['IL',10'Bar']
功能部件(一){
i=i | |'';
var parts=i.match(/^([a-z]+)([0-9]+)(\s.*)$/i);
如有(部分){
返回[
第[1]部分,
parseInt(第[2]和第10部分),
第[3]部
];
}
返回[];//错误
}
ary.sort(函数(a,b){
//抓住零件
var _a=getParts(a),
_b=零件(b);
//解析问题(两个都失败=无移位,否则
//将元素移动到阵列的末尾)
if(_a.length==0&&u b.length==0)返回0;
如果(_a.length==0)返回-1;
如果(_b.length==0)返回1;
//比较字母部分
if(_a[0]<_b[0])返回-1;
if(_a[0]>_b[0])返回1;
//字母是相等的,继续。。。
//比较数字部分
如果(_a[1]<_b[1])返回-1;
如果(_a[1]>_b[1])返回1;
//数字相等,继续。。。
//比较剩余字符串
如果(_a[2]<_b[2])返回-1;
if(_a[2]>_b[2])返回1;
//字符串相等,请继续。。。
//精确匹配
返回0;
});

我非常喜欢乔治的解决方案,但我需要下划线(“u”)在数字之前排序。下面是我如何修改他的代码:

var chunkRgx=/(+)|([0-9]+)|([^0-9]+)/g;
函数自然比较(a,b){
var ax=[],bx=[];
a、 替换(chunkRgx,函数(_,$1,$2,$3){
ax.push([$1 | | |“0”、$2 | | | |无穷大、$3 | | |“]))
});
b、 替换(chunkRgx,函数(_,$1,$2,$3){
bx.push([$1 | | |“0”,$2 | | |无穷大,$3 | | |“]))
});
while(ax.length&&bx.length){
var an=ax.shift();
var bn=bx.shift();
var nn=an[0]。本地比较(bn[0])||
(an[1]-bn[1])||
an[2]。localeCompare(bn[2]);
如果(nn)返回nn;
}
返回ax.length-bx.length;
}
/////////////////////////
测试=[
“img12.png”,
“img10.png”,
“img2.png”,
“img1.png”,
“img101.png”,
“img101a.png”,
“abc10.jpg”,
“abc10”,
“abc2.jpg”,
“20.jpg”,
"20",
“abc”,
“abc2”,
“_abc”,
“_ab_c”,
“_ab___c”,
“_abc_d”,
“阿伯”,
“abc”,
“_ab_cd”,
""
];
测试.排序(自然比较)

document.write(“+JSON.stringify(test,0,3))
var ary = ["IL0 Foo", "PI0 Bar", "IL10 Hello", "IL10 Baz", "IL3 Bob says hello"];

// break out the three components in to an array
// "IL10 Bar" => ['IL', 10, 'Bar']
function getParts(i){
    i = i || '';
    var parts = i.match(/^([a-z]+)([0-9]+)(\s.*)$/i);
    if (parts){
        return [
            parts[1],
            parseInt(parts[2], 10),
            parts[3]
        ];
    }
    return []; // erroneous
}
ary.sort(function(a,b){
    // grab the parts
    var _a = getParts(a),
        _b = getParts(b);

    // trouble parsing (both fail = no shift, otherwise
    // move the troubles element to end of the array)
    if(_a.length == 0 && _b.length == 0) return 0;
    if(_a.length == 0) return -1;
    if(_b.length == 0) return 1;

    // Compare letter portion
    if (_a[0] < _b[0]) return -1;
    if (_a[0] > _b[0]) return 1;
    // letters are equal, continue...

    // compare number portion
    if (_a[1] < _b[1]) return -1;
    if (_a[1] > _b[1]) return 1;
    // numbers are equal, continue...

    // compare remaining string
    if (_a[2] < _b[2]) return -1;
    if (_a[2] > _b[2]) return 1;
    // strings are equal, continue...

    // exact match
    return 0;
});
var naturalSort=函数(a,b){
a=(''+a).replace(/(\d+)/g,函数(n){return('0000'+n).slice(-5)});
b=(''+b).replace(/(\d+)/g,函数(n){return('0000'+n).slice(-5)});
返回a.localeCompare(b);
}
var naturalSortModern=函数(a,b){
return(“”+a).localeCompare(“”+b),'en',{numeric:true});
}
console.dir([“il0foo”、“pi0bar”、“il10baz”、“il3bob说你好”].sort(naturalSort));
console.dir(([“il0foo”,“pi0bar”,“il10baz”,“il3bob说你好])排序
var ary = ["IL0 Foo", "PI0 Bar", "IL10 Hello", "IL10 Baz", "IL3 Bob says hello"];

// break out the three components in to an array
// "IL10 Bar" => ['IL', 10, 'Bar']
function getParts(i){
    i = i || '';
    var parts = i.match(/^([a-z]+)([0-9]+)(\s.*)$/i);
    if (parts){
        return [
            parts[1],
            parseInt(parts[2], 10),
            parts[3]
        ];
    }
    return []; // erroneous
}
ary.sort(function(a,b){
    // grab the parts
    var _a = getParts(a),
        _b = getParts(b);

    // trouble parsing (both fail = no shift, otherwise
    // move the troubles element to end of the array)
    if(_a.length == 0 && _b.length == 0) return 0;
    if(_a.length == 0) return -1;
    if(_b.length == 0) return 1;

    // Compare letter portion
    if (_a[0] < _b[0]) return -1;
    if (_a[0] > _b[0]) return 1;
    // letters are equal, continue...

    // compare number portion
    if (_a[1] < _b[1]) return -1;
    if (_a[1] > _b[1]) return 1;
    // numbers are equal, continue...

    // compare remaining string
    if (_a[2] < _b[2]) return -1;
    if (_a[2] > _b[2]) return 1;
    // strings are equal, continue...

    // exact match
    return 0;
});