Ruby:除一个元素之外的排序

3

我正在尝试对数组中的字符串元素进行排序。假设我想按照 [b, e, f, t, g] 的顺序进行排序,但是希望在 ruby 中将 e 保留在第一位。因此结果应该是 [e, b, f, g, t]。我该如何编写 Ruby 代码以按这种方式对数组进行排序。

最初的回答:

arr = ["b", "e", "f", "t", "g"]
arr.sort_by! { |x| x == "e" ? -1 : arr.index(x) }

如果有多个 e,会怎么样? - undefined
假设只有一个e;这只是一个例子;在我的情况下,我会使用"default" - user11113981
arr.sort.unshift(arr.delete('e'))。仅适用于包含唯一字符的数组,并且 'e' 必须存在,否则将返回 nil - undefined
4个回答

5
["b", "e", "f", "t", "g"] .sort_by { |s| [s == 'e' ? 0 : 1, s] }
  #=> ["e", "b", "f", "g", "t"] 

在这里,Enumerable#sort_by 使用Array#<=> 比较块计算出的每个元素对,例如 [0, "e"][1, "b"]。请参见文档中有关Array#<=>的第三段。


1
你还可以使用s == 'e' ? '' : " #{s}"或者更好的是"#{ s unless s == 'e' }",假设没有nil元素或空字符串。 - undefined

2
你可以将Array分成所有的“e”和所有不是“e”的部分,然后将它们合并在一起,如下所示。"最初的回答"
  arr = ["b", "e", "f", "t", "e","g"]
  arr.partition {|e| e == 'e'}.reduce {|e,not_e| e.concat(not_e.sort)}
  #=> ["e", "e", "b", "f", "g", "t"]    

感谢@iGian提供的帮助。

最初的回答:

  arr.sort.partition {|e| e == 'e'}.flatten
  #=> ["e", "e", "b", "f", "g", "t"]    

1
partition这个想法不错!还有arr.sort.partition {|e| e == 'e'}.flatten - undefined
1
@iGian 确实值得添加 - undefined

1

再添加一个选项,将其转换为哈希表:

ary = [:b, :e, :f, :t, :g, :e]
ary.sort.group_by(&:itself).then { |h| h.delete(:e) + h.values.flatten }

它返回一个数组,将所有的:e放在前面。 :e必须存在。
#=> [:e, :e, :b, :f, :g, :t]

第一部分是返回已排序的分组哈希表:

ary.sort.group_by(&:itself) #=> {:b=>[:b], :e=>[:e, :e], :f=>[:f], :g=>[:g], :t=>[:t]}


为了使该方法在没有:e的情况下也能正常工作:

ary.sort.group_by(&:itself).then { |h| h.delete(:e).to_a + h.values.flatten }

由于 nil.to_a #=> []


0
你可以试试这个:
 arr.sort.reject{|x| x=="e"}.unshift('e')

如果数组中有超过 "e" 的元素,则会忽略所有的 'e'。

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