什么是在ruby中对字符串进行排序以使空字符串位于末尾的好方法?

时间:2018-07-10 17:20:09

标签: ruby

在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以将空字符串放在最后?仅映射到没有空字符串的数组,排序,然后在末尾填充空字符串会更好吗?还有其他方法吗?

4 个答案:

答案 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本质上是一种“反向排序”-因此,如果将一个空字符串与之进行比较,则将其排在结果的末尾而不是开始。