我有一个奇怪的数组,我需要以某种方式进行排序,我不确定它是否可以在没有大量手工劳动的情况下完成。
考虑一下数组:[ '1a', '2a', '2aa', '5-6', '1', '2', '3', '20' , '7', '8']
它是一个字符串数组。正确排序后,它将如下所示:
[ '1', '1a', '2', '2a', '2aa', '3', '5-6', '7', '8', '20' ]
可以把它想象成某种轮廓编号系统。
我怎么能按这个顺序排序呢?
下面是一个jsfiddle,展示了常规排序如何使用其默认的词典编排行为来处理它(它实际上非常接近它需要的状态):
http://jsfiddle.net/qkE9m/
我在node.js中工作,可以随时使用underscore.js。
发布于 2012-11-03 01:13:35
好的,这是我解决这个问题的尝试。代码现在相当冗长,但我正在研究如何缩小它,并将在我进行的过程中更新我的答案。这应该足以解决问题,让你继续前进。我将把我的代码作为一个节点模块发布,因为那是你的环境。
它的要点是,它将项目分解为可以单独排序的单独部分。它并行地循环这些数组中的每个数组,一旦发现不匹配,它将运行基本的排序比较。
sorter.js
// regex patterns to determine how to "parse" an input item
var patterns = [
/^([a-zA-Z]+)$/, // only letters
/^(\d+)$/, // only contains an integer
/^(\d+)\-\d+$/, // contains 2 integers separated by a hyphen
/^(\d+)([a-z]+)?\-(\d+)([a-z]+)?$/, // contains a 2 integer/letter combos separated by a hyphen
/^(\d+)([a-z]+)$/ // contains an integer followed by letters
];
function itemComparator(item) {
var len = patterns.length,
matches, x, regex;
for (x = 0; x < len; x++) {
regex = patterns[x];
if (regex.test(item)) {
matches = item.match(regex).slice(1);
if (/^\d+$/.test(matches[0])) {
matches[0] = parseInt(matches[0], 10);
}
return matches;
}
}
throw new Error("could not parse item for comparison: " + item);
}
module.exports = function (a, b) {
var compA = itemComparator(a),
compB = itemComparator(b),
x, len, tmpA, tmpB, typeA, typeB; // tmp vars
// find the largest size, so we don't miss anything
len = Math.max(compA.length, compB.length);
// loop each comp arr in parallel
for (x = 0; x < len; x += 1) {
// store for speed
tmpA = compA[x];
tmpB = compB[x];
typeA = typeof tmpA;
typeB = typeof tmpB;
// if the elements are not equal
if (tmpA !== tmpB) {
// then do the comparison, and stop the loop
if (typeA === typeB) {
return tmpA < tmpB ? -1 : 1;
} else if (typeA === "undefined") {
return -1;
} else if (typeB === "undefined") {
return 1;
} else if (typeA === "string") {
return -1;
} else if (typeB === "string") {
return 1;
} else {
console.warn("unexpected condition for %s (%s) and %s (%s)", tmpA, typeA, tmpB, typeB);
return 0;
}
}
}
};
test.js
var sorter = require("./sorter"),
arr = [
'1a', 'aa', '2a', '2aa', '5-6', '1', '2', '3', 'DBA', 'bb',
'20', '2b', '7', '8', '125a', '33a-35', 'ABC',
'3aaa-4c', '3aaa-52d', 'AA', 'c', '5dd', 'aa'
];
console.log(arr.sort(sorter));
// [ 'AA',
// 'ABC',
// 'DBA',
// 'aa',
// 'aa',
// 'bb',
// 'c',
// '1',
// '1a',
// '2',
// '2a',
// '2aa',
// '2b',
// '3',
// '3aaa-4c',
// '3aaa-52d',
// '5-6',
// '5dd',
// '7',
// '8',
// '20',
// '33a-35',
// '125a' ]
发布于 2012-11-03 00:30:50
我不知道您的实际数据是什么样子,但我认为这应该会推动您朝着正确的方向前进:
[ '1a', '2a', '2aa', '5-6', '1', '2', '3', '20' , '7', '8'].sort(function(a,b)
{
if (parseFloat(a) !== parseFloat(b))
{
return parseFloat(a) - parseFloat(b);
}
if (a.charAt(0) !== b.charAt(0))
{//just to be on the safe side
return +(a[0]) - +(b[0]);
}
return a.length - b.length;
});
//result:
["1", "1a", "2", "2a", "2aa", "3", "5-6", "7", "8", "20"]
https://stackoverflow.com/questions/13199251
复制相似问题