【问题标题】:Traverse Nested Ruby Hash With Array of Keys使用键数组遍历嵌套的 Ruby 哈希
【发布时间】:2017-04-03 00:28:07
【问题描述】:

给定一个包含 n 层嵌套值、一个字段名和一个路径的散列

contact = {
  "Email" => "bob@bob.com",
  "Account" => {
    "Exchange" => true,
    "Gmail" => false,
    "Team" => {
      "Closing_Sales" => "Bob Troy",
      "Record" => 1234
    }
  }
}

field = "Record"
path = ["Account", "Team"] #Must support arbitrary path length

如何定义一种方法来检索路径末尾的字段值。

def get_value(hash, field, path)
  ?
end

get_value(contact, "Record", ["Account", "Team"])
=> 1234

【问题讨论】:

  • 你的问题写得很好。下次考虑在选择答案之前稍等片刻。快速选择可能会阻止其他答案,并使仍在研究答案的人短路。 (不过,在我开始写我的答案之前,你已经选择了一个答案。)
  • 你好@CarySwoveland - 感谢您的建议,我下次一定会这样做。刚开始真正使用 StackExchange,所以我有点菜鸟。你的回答很好。

标签: arrays ruby hashtable


【解决方案1】:

你可以用Array#inject: 来表示hash['Account']['Team'] 然后return_value_of_inject['Record']:

def get_value(hash, field, path)
  path.inject(hash) { |hash, x| hash[x] }[field]
end

get_value(contact, field, path) # => 1234

顺便说一句,get_value(contact, ['Account', 'Team', 'Record']) 怎么样?

def get_value2(hash, path)
  path.inject(hash) { |hash, x| hash[x] }
end

get_value2(contact, ['Account', 'Team', 'Record']) # => 1234

get_value(contact, 'Account.Team.Record')

def get_value3(hash, path)
  path.split('.').inject(hash) { |hash, x| hash[x] }
end

get_value3(contact, 'Account.Team.Record')   # => 1234

【讨论】:

    【解决方案2】:
    def get_value(contact, field, path)
      path.inject(contact) {|p, j| p.fetch(j, {}) }.fetch(field, nil)
    end
    

    【讨论】:

    • 你可以写(path + [field]).inject(contact) {|p, j| p.fetch(j, {}) }来简化一点。
    【解决方案3】:

    让我们将“字段”视为“路径”的最后一个元素。那么就简单了

    def grab_it(h, path)
      h.dig(*path)
    end
    
    grab_it contact, ["Account", "Team", "Record"]
      #=> 1234 
    grab_it contact, ["Account", "Team", "Rabbit"]
      #=> nil
    grab_it(contact, ["Account", "Team"]
      # => {"Closing_Sales"=>"Bob Troy", "Record"=>1234} 
    grab_it contact, ["Account"]
      #=> {"Exchange"=>true, "Gmail"=>false, "Team"=>{"Closing_Sales"=>"Bob Troy",
      #    "Record"=>1234}} 
    

    Hash#dig 在 v2.3 中添加。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-12-11
      • 1970-01-01
      • 2014-12-30
      • 1970-01-01
      • 2013-11-25
      • 1970-01-01
      相关资源
      最近更新 更多