Ruby - 如何以最少的迭代对数组进行排序
Ruby - How to sort through arrays with minimal iterations
目前我有一个数组中的随机游戏列表。
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
这是我迄今为止最好的成绩。但是,我想知道是否有任何其他算法或其他方法可以改善这一点?
[编辑:发布此答案后,我注意到您想对 year
进行排序,然后对 "Creator"
字段进行排序。这是不可能的,因为每个 "Creator"
都会有多场不同年份的比赛。如果你想使用 years
作为排序标准,你将必须指定如何完成,但对于这个问题来说为时已晚。]
我遇到了问题 运行 你的代码,但基本思路没问题。我建议您解决的一件事是排序。通过对字符串进行排序,"Creator11" 排在 "Creator2".
之前
有很多方法可以做到这一点,我怀疑您是否会注意到性能差异,除非您有一个非常大的数组(包括您的方法)。我将给出一个使用Hash#update (aka merge!
) that uses a block to determine the value when both hashes being merged have the same key. Someone else may offer a solution that use the method 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"]}
在块变量中看到 _
的地方,表示我没有在块中使用该变量。 (但是,_
是一个变量,因此被分配了一个值)。
目前我有一个数组中的随机游戏列表。
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
这是我迄今为止最好的成绩。但是,我想知道是否有任何其他算法或其他方法可以改善这一点?
[编辑:发布此答案后,我注意到您想对 year
进行排序,然后对 "Creator"
字段进行排序。这是不可能的,因为每个 "Creator"
都会有多场不同年份的比赛。如果你想使用 years
作为排序标准,你将必须指定如何完成,但对于这个问题来说为时已晚。]
我遇到了问题 运行 你的代码,但基本思路没问题。我建议您解决的一件事是排序。通过对字符串进行排序,"Creator11" 排在 "Creator2".
之前有很多方法可以做到这一点,我怀疑您是否会注意到性能差异,除非您有一个非常大的数组(包括您的方法)。我将给出一个使用Hash#update (aka merge!
) that uses a block to determine the value when both hashes being merged have the same key. Someone else may offer a solution that use the method 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"]}
在块变量中看到 _
的地方,表示我没有在块中使用该变量。 (但是,_
是一个变量,因此被分配了一个值)。