JavaScript 中字母数字字符串的自然排序(不包括十六进制)

问题描述 投票:0回答:1

我正在寻找一种有效的方法来对字母数字标签列表进行排序,但忽略对十六进制值进行排序,如下所示。

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"
]

请注意,可以在标签中不使用 (_) 来根据该特定字符拆分每个标签以提取非数字部分

javascript sorting hex natural-sort
1个回答
0
投票

您需要在

_
(下划线)上进行拆分并首先比较左侧的值。如果它们相同,请检查正确的值。您需要确定值的“类型”。我创建了一个名为
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));

© www.soinside.com 2019 - 2024. All rights reserved.