在Ruby中对字符串和数字进行排序

我想首先按字符串排序数组,然后是数字。 我该怎么做呢?

解决棘手排序的一般技巧是使用#sort_by,块返回一个具有主要和次要排序顺序的数组(如果需要,还可以使用三级等)

a = ['foo', 'bar', '1', '2', '10'] b = a.sort_by do |s| if s =~ /^\d+$/ [2, $&.to_i] else [1, s] end end pb # => ["bar", "foo", "1", "2", "10"] 

这是有效的,因为Ruby定义了数组比较的方式。 比较由Array#<=>方法定义:

数组以“元素方式”进行比较; 使用<=>运算符将ary的第一个元素与other_ary的第一个元素进行比较,然后将每个第二个元素等进行比较……一旦这样的比较结果为非零(即两个相应的元素不相等) ),为整个数组比较返回该结果。

通过将数字放在第一个按顺序排序,然后按顺序排列第二个字符串,按顺序排序混合数字和字符串数组。

 >> a = [1, 2, "b", "a"] >> a.partition{|x| x.is_a? String}.map(&:sort).flatten => ["a", "b", 1, 2] 
 a = ['1', '10', '100', '2', '42', 'hello', 'x1', 'x20', 'x100', '42x', '42y', '10.1.2', '10.10.2', '10.8.2'] a.map {|i| i.gsub(/\d+/) {|s| "%08d" % s.to_i } }.zip(a).sort.map{|x,y| y} # => ["1", "2", "10", "10.1.2", "10.8.2", "10.10.2", "42", "42x", "42y", "100", "hello", "x1", "x20", "x100"] 

通常,首先使用数字进行字母化。 如果要按字母顺序排列字母在数字前按字母顺序排列,则需要更改使用的比较函数。

 # I realize this function could be done with less if-then-else logic, # but I thought this would be clearer for teaching purposes. def String.mysort(other) length = (self.length < other.length) ? self.length : other.length 0.upto(length-1) do |i| # normally we would just return the result of self[i] <=> other[i]. But # you need a custom sorting function. if self[i] == other[i] continue # characters the same, skip to next character. else if self[i] ~= /[0-9]/ if other[i] ~= /[0-9]/ return self[i] <=> other[i] # both numeric, sort normally. else return 1 # self is numeric, other is not, so self is sorted after. end elsif other[i] ~= /[0-9]/ return -1 # self is not numeric, other is, so self is sorted before. else return self[i] <=> other[i] # both non-numeric, sort normally. end end end # if we got this far, the segments were identical. However, they may # not be the same length. Short sorted before long. return self.length <=> other.length end ['0','b','1','a'].sort{|x,y| x.mysort(y) } # => ['a', 'b', '0', '1'] 

这是一个有点冗长的答案。 将数组划分为两个子数组:字符串和数字,对它们进行排序并将它们连接起来。

 array = [1, 'b', 'a', 'c', 'd', 2, 4, 3] strings = [] numbers = [] array.each do |element| if element.is_a? String strings << element else numbers << element end end sorted_array = strings.sort + numbers.sort sorted_array # ['a', 'b', 'c', 'd', 1, 2, 3, 4] 

如果您尝试对Mixed case和数字进行排序,那么地球上只有少数人可以在专有应用程序之外进行排序。 这是一个带有吸盘的秘密。 您必须使用qsort,这样可以轻松排序,直到混合大小写(大写和小写字母)。 然后大学,书籍和互联网让你垂头丧气。 这个黑客非常重视黄金,并且出于各种原因是编程的铜环。

要使用单词对数字进行排序,必须将数字转换为字符串 你必须使用大写预先分配。 如果你有更少的单词“Ant”,“ant”和“anT”,他们都应该指向大写排序列表中的单词“ANT”。 然后,您将创建一个仅包含这三个单词[“Ant”,“ant”和“anT”]的列表(数组),并使用qsort作为绑定断路器对它们进行排序。

然后将它们插入到最终的排序数组中。 设计相当困难。 “A”在ascii上是65,“a”是97,在’Z’和’a’之间有很多垃圾字符! 这不是偶然的! 这是我告诉你的阴谋!

您可以创建一个排序表,对字符进行更合理的分组:

A,a,B,b,C,c,D,d,E,e,F,f,G,g,H,h,I,i,J,j,K,k,L,l,M, m,N,n,… 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 …

围绕此块构建表,以“”(空格)ascii 32到128开始。您可能希望按顺序重新排序A 65中的数字。

这使得它更容易,但可能会导致性能损失超出大多数编程语言的宏。 祝好运!