聪明的排序(排序可能包含或不包含数字的字符串)[重复]

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));

【讨论】:

非常好,谢谢。

以上是关于聪明的排序(排序可能包含或不包含数字的字符串)[重复]的主要内容,如果未能解决你的问题,请参考以下文章

如何对包含数字的字符串列表进行数字排序?

在 Pandas 中对包含数字和分隔符的字符串进行排序

如何在iOS中对包含数字和名称的字符串数组进行排序

您可以按值对包含数字的字符串数组进行排序吗? [复制]

对包含数字字符串的文件名数组进行排序

C中的自然排序 - “字符串数组,包含数字和字母”