简体   繁体   English

使用键数组遍历嵌套的Ruby哈希

[英]Traverse Nested Ruby Hash With Array of Keys

Given a hash with n levels of nested values, a field name, and a path 给定具有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

How can one define a method that would retrieve the field value at the end of the path. 如何定义一个方法来检索路径末尾的字段值。

def get_value(hash, field, path)
  ?
end

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

You can use Array#inject : to mean hash['Account']['Team'] then, return_value_of_inject['Record'] : 您可以使用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

BTW, how about get_value(contact, ['Account', 'Team', 'Record']) ? 顺便说一句, 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

or get_value(contact, 'Account.Team.Record') 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

Let's regard the "field" as the last element of the "path". 让我们将“字段”视为“路径”的最后一个元素。 Then it's simply 那就简单了

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 was added in v2.3. Hash#dig在v2.3中添加了。

def get_value(contact, field, path)
  path.inject(contact) {|p, j| p.fetch(j, {}) }.fetch(field, nil)
end

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM