如何对整数和字符串数组进行排序?

9

我正在尝试对一个混合了整数和字符串的数组进行排序。例如:

a = ["a", "b", 5, "c", 4, "d", "a1", "a12", 3, 13, 2, "13a", "12a"]

我尝试了:

a.sort do |x, y|
  if x.class == y.class
    x <=> y
  else
    x.class.to_s <=> y.class.to_s
  end
end

这将返回:

[2, 3, 4, 5, 13, "12a", "13a", "a", "a1", "a12", "b", "c", "d"]

The outcome I want is:

[2, 3, 4, 5, "12a", 13, "13a", "a", "a1", "a12", "b", "c", "d"]

你的字符串中可以包含多个数字吗?例如:"a1b2c3"? - Stefan
什么是正确的?["a1", "a12", "a2"] 还是 ["a1", "a2", "a12"] - Stefan
@Stefan 可以在一个字符串中有多个数字。后者 ["a1", "a2", "a12"] - Christian Fazzini
@ChristianFazzini,更新后的版本即使在字符串中有多个数字的情况下也能正常工作。快去试试吧。 - ndnenkov
1个回答

11
a.sort_by { |x| [(x.to_s.match(/^\d+/) ? x.to_i : 1.0 / 0), x.to_s] }

首先按数值大小排序,其次按字符串值排序。如果字符串不以数字开头,则将数字值强制视为无穷大。


编辑:由于提问者已经澄清了他希望考虑的不仅是前导数字值,而是所有后续数字值,我们可以使用相同的方法,只是这次要对字符串中每个单独的数字和非数字实体应用它:

a.sort_by do |x|
  x.to_s.split(/(\D+)/).map do |y|
    [(y.match(/\d/) ? y.to_i : 1.0 / 0), y]
  end
end

1
数组中的 0 会出现在 "13a""a" 之间。 - Stefan
这样更好,但它无法正确地排序["a13", "a2"] - Stefan
1
@Stefan,再次更新。 - ndnenkov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接