我有一个包含以下值的数组
asd sdf dsdf 1sadf *sdf !sdf @asdf _asd .sadf (sadf )sadf #sadf
^asdf &asdf %asdf -sadf =sadf +sadf -sdf
我希望在javascript中按以下方式将其排序为三个部分。
所以这应该是排序数组的序列。
修改: 这是我一直在尝试的功能:
function naturalSort(a, b) {
a = a.path.toLowerCase();
b = b.path.toLowerCase();
var re = /(^-?[0-9]+(\.?[0-9]*)[df]?e?[0-9]?$|^0x[0-9a-f]+$|[0-9]+)/gi,
sre = /(^[ ]*|[ ]*|[_]*$)/g,
dre = /(^([\w ]+,?[\w ]+)?[\w ]+,?[\w ]+\d+:\d+(:\d+)?[\w ]?|^\d{1,4}[\/\-]\d{1,4}[\/\-]\d{1,4}|^\w+, \w+ \d+, \d{4})/,
hre = /^0x[0-9a-f]+$/i,
ore = /^0/,
// convert all to strings and trim()
x = a.toString().replace(sre, '') || '',
y = b.toString().replace(sre, '') || '',
// chunk/tokenize
xN = x.replace(re, '\0$1\0').replace(/\0$/, '').replace(/^\0/, '').split('\0'),
yN = y.replace(re, '\0$1\0').replace(/\0$/, '').replace(/^\0/, '').split('\0'),
// numeric, hex or date detection
xD = parseInt(x.match(hre)) || (xN.length != 1 && x.match(dre) && Date.parse(x)),
yD = parseInt(y.match(hre)) || xD && y.match(dre) && Date.parse(y) || null;
// first try and sort Hex codes or Dates
if (yD)
if (xD < yD) return -1;
else if (xD > yD) return 1;
// natural sorting through split numeric strings and default strings
for (var cLoc = 0, numS = Math.max(xN.length, yN.length); cLoc < numS; cLoc++) {
// find floats not starting with '0', string or 0 if not defined (Clint Priest)
oFxNcL = !(xN[cLoc] || '').match(ore) && parseFloat(xN[cLoc]) || xN[cLoc] || 0;
oFyNcL = !(yN[cLoc] || '').match(ore) && parseFloat(yN[cLoc]) || yN[cLoc] || 0;
// handle numeric vs string comparison - number < string - (Kyle Adams)
if (isNaN(oFxNcL) !== isNaN(oFyNcL)) return (isNaN(oFxNcL)) ? -1 : 1;
// rely on string comparison if different types - i.e. '02' < 2 != '02' < '2'
else if (typeof oFxNcL !== typeof oFyNcL) {
oFxNcL += '';
oFyNcL += '';
}
if (oFxNcL <= oFyNcL) return -1;
if (oFxNcL >= oFyNcL) return 1;
}
return 0;
}
答案 0 :(得分:12)
说实话,我根本不知道你发布的功能是什么......
以下方法使用位置匹配来比较第一个字符的字符串。具有相同第一个字符的字符串会定期排序。
顺便说一下,没有测试空字符串。
function MySort(alphabet)
{
return function(a, b) {
var index_a = alphabet.indexOf(a[0]),
index_b = alphabet.indexOf(b[0]);
if (index_a === index_b) {
// same first character, sort regular
if (a < b) {
return -1;
} else if (a > b) {
return 1;
}
return 0;
} else {
return index_a - index_b;
}
}
}
var items = ['asd','sdf', 'dsdf', '1sadf', '*sdf', '!sdf', '@asdf', '_asd', '.sadf', '(sadf', ')sadf', '#sadf', '^asdf', '&asdf', '%asdf', '-sadf', '=sadf', '+sadf', '-sdf', 'sef'],
sorter = MySort('*!@_.()#^&%-=+01234567989abcdefghijklmnopqrstuvwxyz');
console.log(items.sort(sorter));
输出:
["*sdf", "!sdf", "@asdf", "_asd", ".sadf", "(sadf", ")sadf", "#sadf", "^asdf",
"&asdf", "%asdf", "-sadf", "-sdf", "=sadf", "+sadf", "1sadf",
"asd", "dsdf", "sdf", "sef"]
答案 1 :(得分:1)
这也可能起作用:
function sortArray(a, b) {
const digitRegex = /^\d/;
const alphabetRegex = /^[a-zA-Z]/;
const symbolRegex = /^[^\w\s]/;
const scoreA = symbolRegex.test(a) * 1 || digitRegex.test(a) * 10 || alphabetRegex.test(a) * 100;
const scoreB = symbolRegex.test(b) * 1 || digitRegex.test(b) * 10 || alphabetRegex.test(b) * 100;
if (scoreA !== scoreB) {
return scoreA - scoreB;
}
if (a < b) {
return -1;
} else if (a > b) {
return 1;
}
return 0;
}
const a = ['def', '%rec', '456', '^we', '123', 'abc'].sort(sortArray);
console.log(a);
答案 2 :(得分:1)
两个简单的解决方案:
使用 Intl.Collator
myArray.sort(Intl.Collator().compare)
使用 localeCompare
myArray.sort((a, b) => a.localeCompare(b))
Intl.Collator 更高效