在Ruby中,默认排序方式将空字符串放在首位。
['', 'g', 'z', 'a', 'r', 'u', '', 'n'].sort
礼物:
["", "", "a", "g", "n", "r", "u", "z"]
但是,通常需要在 end 处使用空字符串。
做类似的事情:
['', 'g', 'z', 'a', 'r', 'u', '', 'n'].sort { |a, b| a[0] && b[0] ? a <=> b : a[0] ? -1 : b[0] ? 1 : 0 }
工作并给出:
["a", "g", "n", "r", "u", "z", "", ""]
但是,这不是很可读,也不是很灵活。
是否有一种合理且干净的方法来在Ruby中获取sort
以将空字符串放在最后?仅映射到没有空字符串的数组,排序,然后在末尾填充空字符串会更好吗?还有其他方法吗?
答案 0 :(得分:7)
arr = ["g", "u", "", "a", "", "r", "n", "z"]
arr.sort_by { |s| [s.empty? ? 1 : 0, s] }
#=> ["a", "g", "n", "r", "u", "z", "", ""]
或
arr.sort_by { |s| s.empty? ? 255.chr : s }
# => ["a", "g", "n", "r", "u", "z", "", ""]
或
empty, non_empty = arr.partition(&:empty?)
#=> [["", ""], ["g", "u", "a", "r", "n", "z"]]
non_empty.sort.concat empty
#=> ["a", "g", "n", "r", "u", "z", "", ""]
答案 1 :(得分:4)
我能想到的最简单的解决方案是
a = ['', 'g', 'z', 'a', 'r', 'u', '', 'n']
a.sort.rotate(a.count(''))
#=> ["a", "g", "n", "r", "u", "z", "", ""]
Array#rotate
:通过旋转self来返回新数组,以使count处的元素成为新数组的第一个元素。
因此,我们仅按空字符串(""
)的数量进行轮换
答案 2 :(得分:2)
只需计算空白的数量,然后使用#rotate
将其移到末尾即可:
sorted = ['', 'g', 'z', 'a', 'r', 'u', '', 'n'].sort
blank_count = sorted.count &:empty?
sorted.rotate! blank_count
答案 3 :(得分:1)
这是另一个变体,定义了自定义sort
比较:
arr = ["g", "u", "", "a", "", "r", "n", "z"]
arr.sort { |s1, s2| (s1.empty? || s2.empty?) ? (s2 <=> s1) : (s1 <=> s2) }
#=> ["a", "g", "n", "r", "u", "z", "", ""]
使用s2 <=> s1
本质上是一种“反向排序”-因此,如果将一个空字符串与之进行比较,则将其排在结果的末尾而不是开始。