Ruby-sort_by多级排序

时间:2016-11-08 00:23:31

标签: ruby sorting

我有两个字符串,s1s2

我想要一个字符列表(来自两个字符串),已排序:

  • 首先字符在其中一个字符串中出现的次数(值越大)

e.g。 "hello""goodbye""lloogbehyd"

  • 是否最大字符是否出现在s1或s2

e.g。 "hello""goodbye""lloohegdby"

  • 第三按字母顺序

e.g。 "hello""goodbye""lloohebdgy"

目前我有这段代码:

letters = (s1+s2).chars.uniq.sort_by{ |s| [s1.count(s), s2.count(s)].max }.reverse

按第一个条件排序,如何添加其他级别?

2 个答案:

答案 0 :(得分:0)

使用String#count效率相对较低,因为遍历每个唯一字母的整个字符串。以更多代码行为代价创建计算哈希会更有效率,可以按照以下方式完成(参见Hash::new)。

s1 = "hello"
s2 = "goodbye"

h1 = s1.each_char.with_object(Hash.new(0)) { |c,h| h[c] += 1 }
  #=> {"h"=>1, "e"=>1, "l"=>2, "o"=>1} 
h2 = s2.each_char.with_object(Hash.new(0)) { |c,h| h[c] += 1 }
  #=> {"g"=>1, "o"=>2, "d"=>1, "b"=>1, "y"=>1, "e"=>1}
hmx = (h1.keys | h2.keys).each_with_object({}) do |c,h| h[c] =
  case h1[c] <=> h2[c]
  when 1 then [-h1[c], -1]
  when 0 then [-h1[c], 0]
  else [-h2[c], 1]
  end
end
  #=> {"h"=>[-1, -1], "e"=>[-1, 0], "l"=>[-2, -1], "o"=>[-2, 1],
  #    "g"=>[-1, 1], "d"=>[-1, 1], "b"=>[-1, 1], "y"=>[-1, 1]} 

我们现在可以使用排序 Enumerable#sort_by

(s1+s2).each_char.sort_by { |c| [*hmx[c], c] }.join
  #=> "lloooheebdgy"

有关如何对数组进行排序的说明,请参阅Array#<=>(第三段)。

我假设如果两个字符中的一个中出现最多出现两个字符,则会为每个字符分配-101的分数。得分最低的角色(如果他们没有相同的分数)在排序中的另一个角色之前。如果字符c包含的字符-1比字符串s1多,则c字符的分数为s1;如果两个字符串包含相同数量的0,则得分为c;如果1包含的s2c更多,则得分为s1

答案 1 :(得分:0)

我最终做了什么:

(s1+s2).chars.sort_by{ |s| 
  [-([s1.count(s), s2.count(s)].max), 
    s1.count(s) > s2.count(s) ? -1 : 1, 
    s]
}
#=> "lloohebdgy"

广义的答案是,Arraysort_by允许您指定排序级别。