聪明的排序(排序可能包含或不包含数字的字符串)[重复]
Posted
技术标签:
【中文标题】聪明的排序(排序可能包含或不包含数字的字符串)[重复]【英文标题】:Clever sorting (Sort strings that may or may not contain numbers) [duplicate] 【发布时间】:2019-05-22 03:36:21 【问题描述】:我需要对可能包含或不包含数字的单位列表进行排序。
例如 ["unit 1", "unit 2", ..., "unit 11"]。
大多数排序函数都会这样排序: 单元 1、单元 11、单元 2..
但我也可能遇到没有编号的情况。 ["apt A", "apt B", ..., "apt Z"].
是否有任何巧妙的解决方案可以正确排序:
第 1 单元,第 2 单元,...,第 11 单元。
apt A, apt B, ..., apt Z。
【问题讨论】:
整个列表会包含数字或字母,还是两者都包含?如果它包含混合物,那么预期的顺序是什么? 它可以包含两者的混合。我们希望先按字母排序,然后按数字排序。例如 ["unit 1", "unit 2", "unit 11", "apt 1", "apt 2"] 应该排序为:[apt 1, apt 2, unit 1, unit 2, unit 11]。 对不起,我想我的问题措辞可能有误。['apt A', 'apt B', 'apt 1', 'apt 2']
可以混用吗?
是的,这是可能的。那应该是。 ['apt 1', 'apt 2', 'apt A', 'apt B',]
这通常被称为“自然排序”。或许你可以在现有的natural sort questions中找到答案
【参考方案1】:
鉴于 cmets 中的说明,您可以按 /(\d+)/g
拆分每个字符串,并按结果字符串数组中的每个元素进行排序。将偶数索引视为字符串,将奇数索引视为数字:
const input = ['unit 11', 'unit 1', 'unit 2', 'apt 11', 'apt 1', 'apt 2', 'unit A', 'unit c', 'unit B', 'apt a', 'apt C', 'apt b'];
function customSort (a, b)
a = a.toUpperCase().split(/(\d+)/g);
b = b.toUpperCase().split(/(\d+)/g);
const length = Math.min(a.length, b.length);
for (let i = 0; i < length; i++)
const cmp = (i % 2)
? a[i] - b[i]
: -(a[i] < b[i]) || +(a[i] > b[i]);
if (cmp) return cmp;
return a.length - b.length;
console.log(input.sort(customSort));
【讨论】:
非常好,谢谢。以上是关于聪明的排序(排序可能包含或不包含数字的字符串)[重复]的主要内容,如果未能解决你的问题,请参考以下文章