假设我们有一组具有混合名称值的对象(nums,cyrillic,english):
(如果代码不适合你,将undefined更改为’ru’,它也会改变排序结构)
let ascending = true var items = [ {name: 'c',value: ''},{name: 'b',{name: 'a',{name: 'д',{name: 'в',{name: '41',{name: 'а',{name: 'б',{name: '0',{name: '31',{name: '4',{name: 'г',value: ''} ] items.sort(function (a,b) { // ascending order if (ascending) { return a.name.localeCompare(b.name,undefined,{ numeric: true }); } // descending order else { return b.name.localeCompare(a.name,{ numeric: true }); } }) console.log(items);
目前的结果
我按升序获得排序数组,结构如下:
> Nums(升序)
>英语(升序)
>非英语(升序)
升序= true时的结果:
{name: "0",value: ""} {name: "31",value: ""} {name: "4",value: ""} {name: "41",value: ""} {name: "a",value: ""} {name: "b",value: ""} {name: "c",value: ""} {name: "а",value: ""} {name: "б",value: ""} {name: "в",value: ""} {name: "г",value: ""} {name: "д",value: ""}
期望的结果
我需要它能够在升序= false时按降序对数组进行排序并保留结构:
> Nums(降序)
>英语(降序)
>非英语(降序)
升序= false时需要的结果:
{name: "41",value: ""} {name: "0",value: ""} {name: "c",value: ""}
问题
当我更改ascending = false并使用a.name更改b.name的位置时,它只是将整个数组翻转而不是翻转其“类别”(nums,english,cyrillic)中的值.
我不确定如何正确地做到这一点.我的意思是,反转数组会反转这些值,所以我应该在数组翻转后重组数组“类别”吗?这样的事情可能是:
>使用isNaN()获取带有数字的所有对象,并将它们移到顶部
>然后在[0]处获取仅包含a-z的项目,并将它们移到数字“类别”下方
>其他一切都停留在底部
解决方法
如果您有识别数字,英语和非英语字符串的机制,您可以使用以下想法:
var items = [ { name: "c",value: "" },{ name: "b",{ name: "a",{ name: "д",{ name: "в",{ name: "41",{ name: "а",{ name: "б",{ name: "0",{ name: "31",{ name: "4",{ name: "г",value: "" } ]; function sortFunctionMaker(ascending) { function isNumber(str) { return Number.isNaN(Number(str)) === false; } function isEnglish(str) { return /^[a-zA-Z]+$/.test(str); } return function(a,b) { var aw,bw; if (isNumber(a.name)) { aw = 1; } else if (isEnglish(a.name)) { aw = 2; } else { aw = 3; } if (isNumber(b.name)) { bw = 1; } else if (isEnglish(b.name)) { bw = 2; } else { bw = 3; } if (aw !== bw) { // a and b belong to different categories // no further comparison is needed return aw - bw; } else if (aw === 1) { // both are numbers // sort mathematically return (ascending ? 1 : -1) * (a.name - b.name); } else { // both are english or otherwise // sort using localeCompare return (ascending ? 1 : -1) * a.name.localeCompare(b.name); } } } items.sort(sortFunctionMaker(true)); console.log("Ascending"); items.forEach(function(item) { console.log(item.name); }); items.sort(sortFunctionMaker(false)); console.log("Descending"); items.forEach(function(item) { console.log(item.name); }); console.groupEnd();