我想首先按字符串对数组进行排序,然后是数字。我该怎么做?
答案 0 :(得分:17)
对数字和字符串数组进行排序,先将数字放在第一位,按顺序排在第二位,然后按顺序排列。
>> a = [1, 2, "b", "a"]
>> a.partition{|x| x.is_a? String}.map(&:sort).flatten
=> ["a", "b", 1, 2]
答案 1 :(得分:15)
解决棘手排序的一般技巧是使用#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
p b # => ["bar", "foo", "1", "2", "10"]
这是有效的,因为Ruby定义了数组比较的方式。比较由Array#<=>方法定义:
阵列以“元素方式”进行比较;使用&lt; =&gt;将ary的第一个元素与other_ary的第一个元素进行比较。运算符,然后是每个第二个元素等等......只要任何这样的比较结果不为零(即两个相应的元素不相等),就会返回整个数组比较的结果。
答案 2 :(得分:3)
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"]
答案 3 :(得分:2)
通常,首先使用数字进行字母化。如果你想按字母顺序排列字母在数字前按字母顺序排列的东西,你需要改变使用的比较函数。
# 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']
答案 4 :(得分: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]
答案 5 :(得分:0)
如果您尝试对混合案例和数字进行排序,那么地球上只有少数人可以在专有应用程序之外执行此操作。这是一个傻逼的秘密。您必须使用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中的数字。
这使得它更容易,但可能会导致性能损失超出大多数编程语言的宏。祝好运!