我正在寻找一种有效的方法来对字母数字标签列表进行排序,但忽略对十六进制值进行排序,如下所示。
arr = [
"a_19",
"a_2",
"b_645500",
"b_6d4500"
]
我已阅读解决方案这里
使用 { numeric: true } 将导致十六进制值之间的排序错误,而不是显示的字符串标签
arrNumeric = [
"a_2",
"a_19",
"b_6d4500",
"b_645500"
]
删除数字标志将导致“a_19”和“a_2”之间的排序错误。
arrNonNumeric = [
"a_19",
"a_2",
"b_645500",
"b_6d4500"
]
所需的排序数组是:
arrSorted = [
"a_2",
"a_19",
"b_645500",
"b_6d4500"
]
请注意,可以在标签中不使用 (_) 来根据该特定字符拆分每个标签以提取非数字部分
您需要在
_
(下划线)上进行拆分并首先比较左侧的值。如果它们相同,请检查正确的值。您需要确定值的“类型”。我创建了一个名为 valueType
的简单函数,用于确定给定字符串是十进制 (dec
)、十六进制 (hex
) 还是字符串 (str
)。
请注意,这是临时的,您应该用
0x6d450
表示十六进制值(前缀为 0x
)。
const valueType = (v) =>
/^\d+$/.test(v) ? 'dec' : /^[a-f0-9]+$/.test(v) ? 'hex' : 'str';
const valueComparator = (a, b) => {
const at = valueType(a), bt = valueType(b);
if (bt !== 'dec' && at === 'dec') return -1; // ^a
if (at !== 'dec' && bt === 'dec') return 1; // ^b
return +a - +b; // Normal integer comparison
}
// Compare left and right values
const customComparator = (a, b) => {
const [ax, ay] = a.split('_'), [bx, by] = b.split('_');
return ax.localeCompare(bx) || valueComparator(ay, by);
}
const arr = [
'a_19',
'a_2',
'b_64550',
'b_6d450',
];
console.log([...arr].sort(customComparator));