【问题标题】:Summing values of identical keys in a deeply nested hash在深度嵌套的哈希中对相同键的值求和
【发布时间】:2019-03-22 17:33:46
【问题描述】:

我之前可能已经发布过这个嵌套哈希。这个散列由每个父键(:home,:away)的4个级别组成。我想访问每个父键的第 4 级,以便将所有 :points 值加在一起,然后我想比较每个求和值并找出哪个是最大值。我自己尝试过这个,但是我得到了一个错误

没有将 Symbol 隐式转换为整数 (repl):136:in []' (repl):136:inblock inwinning_team' (repl):135:in each' (repl):135:inwinning_team' (repl):158:in `'

哈希和我对这段代码的尝试如下,任何解释为什么我得到这个错误以及任何改进以获得所需的输出都会非常有帮助。如果理解的太混乱了,我很抱歉。

game_hash = {
    :home => 
    {
        :team_name => "Brooklyn Nets",
        :colors => ["Black", "White"],
        :players => {
            :player1 => {
                :name => "Alan Anderson",
                :number => 0,
                :shoe_size => 16,
                :points => 22,
                :rebounds => 12,
                :assists => 12,
                :steals => 3,
                :blocks => 1,
                :slam_dunks => 1
            },
            :player2 => {
                :name => "Reggie Evans",
                :number => 30,
                :shoe_size => 14,
                :points => 12,
                :rebounds => 12,
                :assists => 12,
                :steals => 12,
                :blocks => 12,
                :slam_dunks => 7
            },
            :player3 => {
                :name => "Brook Lopez",
                :number => 11,
                :shoe_size => 17,
                :points => 17,
                :rebounds => 19,
                :assists => 10,
                :steals => 3,
                :blocks => 1,
                :slam_dunks => 15
            },
            :player4 => {
                :name => "Mason Plumlee",
                :number => 1,
                :shoe_size => 19,
                :points => 26,
                :rebounds => 12,
                :assists => 6,
                :steals => 3,
                :blocks => 8,
                :slam_dunks => 5
            },
            :player5 => {
                :name => "Jason Terry",
                :number => 31,
                :shoe_size => 15,
                :points => 19,
                :rebounds => 2,
                :assists => 2,
                :steals => 4,
                :blocks => 11,
                :slam_dunks => 1

            }
    },      

    :away =>
    {
        :team_name => "Charlotte Hornets",
        :colors => ["Turquoise", "Purple"],
        :players => {
            :player1 => {
                :name => "Jeff Adrien",
                :number => 4,
                :shoe_size => 18,
                :points => 10,
                :rebounds => 1,
                :assists => 1,
                :steals => 2,
                :blocks => 7,
                :slam_dunks => 2
            },
            :player2 => {
                :name => "Bismak Biyombo",
                :number => 0,
                :shoe_size => 16,
                :points => 12,
                :rebounds => 4,
                :assists => 7,
                :steals => 7,
                :blocks => 15,
                :slam_dunks => 10
            },
            :player3 => {
                :name => "DeSagna Diop",
                :number => 2,
                :shoe_size => 14,
                :points => 24,
                :rebounds => 12,
                :assists => 12,
                :steals => 4,
                :blocks => 5,
                :slam_dunks => 5
            },
            :player4 => {
                :name => "Ben Gordon",
                :number => 8,
                :shoe_size => 15,
                :points => 33,
                :rebounds => 3,
                :assists => 2,
                :steals => 1,
                :blocks => 1,
                :slam_dunks => 0
            },
            :player5 => {
                :name => "Brendon Haywood",
                :number => 33,
                :shoe_size => 15,
                :points => 6,
                :rebounds => 12,
                :assists => 12,
                :steals => 22,
                :blocks => 5,
                :slam_dunks => 12
            }
        }
    }
}
}


    ##winning team
def winning_team(game_data)
  #finding the sum of all :points in :home

  game_data[:home].each do |attribute, value|
    value[:players].each do |player, player_data|
      score_1 = player_data.find{|k| k[:points]}.sum
    end 
  end 

  #finding the sum of all :points in :away
  game_data[:away].each do |attribute, value|
    value[:players].each do |player, player_data|
      score_2 = player_data.find{|k| k[:points]}.sum
    end 
  end 

  #outputting a final statement of who won the game


    if score_1 < score_2 
    puts "Brooklyn Nets won the game"
  else 
    puts "Charlotte Hornets won the game"
  end




end

【问题讨论】:

  • 无耻插件:我维护了一个包iteraptor,它明确设计用于迭代/映射/减少深度嵌套的枚举。您可能想尝试一下。
  • 鼓励问题的作者将他们的例子精简到他们的本质。例如,这里每个玩家有九个属性,但只有一个(:number)与问题相关。例如,如果您只包含两个属性,可能是 ;name:number,那么该示例的相关性也不会降低。

标签: ruby


【解决方案1】:
game_hash[:home][:players].sum { |_, h| h[:points] }
#⇒  96

:away 也一样。

【讨论】:

  • 当我为 :away 执行此操作时收到未定义方法 []' for nil:NilClass (repl):132:in
    ' 的错误
  • 我打赌你可能会自己解决这个问题。我展示了方法。
  • 我不确定它为什么会抛出错误,根据我的理解它应该可以工作
  • 您的哈希格式不正确。 :away 应该与:home 处于同一级别。你的有:away 一层。 game_hash[:home][:away][:players].sum { |_, h| h[:points] } #⇒ 85.
【解决方案2】:

如果您正在寻找获胜的团队,您可以使用 Enumerable#max_byEnumerable#sum

winning_team = game_hash.values.max_by do |team|
  team[:players].sum { |_, h| h[:points] }
end

puts winning_team[:team_name]

或者,您可以使用 Hashie::MashOpenStruct 之类的东西将哈希转换为更友好的对象并使用如下访问器方法:

require 'hashie/mash'
game = Hashie::Mash.new(game_hash)

winning_team = [game.home, game.away].max_by do |team|
  team.players.values.sum(&:points)
end

puts winning_team.team_name

【讨论】:

    猜你喜欢
    • 2014-04-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多