Ruby - 如何使用最少的迭代对数组进行排序

时间:2015-02-26 06:00:25

标签: ruby arrays time-complexity ruby-1.8.7

目前,我有一个阵列中的随机游戏列表。

games=[["Game1", 2014, "Creator1", "Creator2", "Creator3"],
       ["Game4", 2013, "Creator7", "Creator10"],
       ["Game2", 2014, "Creator1"],
       ["Game6", 2012, "Creator9"],
       ["Game3", 1990, "Creator2", "Creator11"],
       ["Game9", 2014, "Creator4"]]

#Which looks like this
Title, Year, Creators
Game1, 2014, Creator1, Creator2, Creator3
Game4, 2013, Creator7, Creator10
Game2, 2014, Creator1
Game6, 2012, Creator9
Game3, 1990, Creator2, Creator11
Game9, 2014, Creator4

我希望按以下顺序对数据进行排序

  • 标题

Creator1  => Game1, Game2
Creator10 => Game4
Creator11 => Game3
Creator2  => Game3, Game1 #<- year: 1990, 2014
Creator3  => Game1
Creator4  => Game9
Creator7  => Game4

目前,我有

def creator_list(games)
    games.sort_by{|x|[-x[1].to_i,x[0]]}
         .inject(Hash.new{|h,k|h[k]=Array.new}) {|h, rw|
         rw[2].each do |a|
             h[a] << rw[0]
         end
         h
         }.to_a.sort_by{|x|x[0]}
end

这是迄今为止我最好的结果。但是,我想知道是否有其他算法或其他方法来改善这一点?

1 个答案:

答案 0 :(得分:0)

[编辑:发布此回答后,我注意到您要对year然后"Creator"字段进行排序。这是不可能的,因为每个"Creator"将有多个不同年份的游戏。如果您想使用years作为排序标准,则必须指定如何完成此操作,但为此问题执行此操作为时已晚。]

我在运行代码时遇到了问题,但基本想法很好。我建议你解决的一件事是排序。通过对字符串进行排序,“Creator11”出现在“Creator2”之前。

有很多方法可以做到这一点,我怀疑你会注意到性能差异,除非你有一个非常大的数组(包括你的方法)。我将给出一个使用Hash#update(aka merge!)形式的解决方案,当使用合并的两个哈希值具有相同的密钥时,它使用块来确定值。其他人可能会提供使用方法Enumerable#group_by的解决方案。

def creator_list(games)
  Hash[games.each_with_object({}) do |(game, year, *creators),h|
    creators.each { |c| h.update(c=>[game]) { |_,ov,nv| ov+nv } }
  end.sort_by { |k,_| k[/\d+$/].to_i }]
end

creator_list(games)
  #=> {"Creator1" =>["Game1", "Game2"],
  #    "Creator2" =>["Game1", "Game3"],
  #    "Creator3" =>["Game1"],
  #    "Creator4" =>["Game9"],
  #    "Creator7" =>["Game4"],
  #    "Creator9" =>["Game6"],
  #    "Creator10"=>["Game4"],
  #    "Creator11"=>["Game3"]} 

如果您看到_的块变量,则表示我没有在块中使用该变量。 (_是一个变量,因此被分配了一个值。)