【问题标题】:How do I search within a nested hash for the value of a specific key?如何在嵌套哈希中搜索特定键的值?
【发布时间】:2017-07-30 04:51:38
【问题描述】:

假设我有一个这样的哈希:

[82] pry(main)> commit2
=> {:sha=>"4df2b779ddfcb27761c71e00e2b241bfa06a0950",
 :commit=>
  {:author=>
    {:name=>"asasa asasa",
     :email=>"asa@asasad.com",
     :date=>2016-08-06 16:24:04 UTC,
     :sha=> "876239789879ab9876c8769287698769876fed"},
   :committer=>
    {:name=>"asasa asasa",
     :email=>"asa@asasad.com",
     :date=>2016-08-06 16:26:45 UTC},
   :message=>
    "applies new string literal convention in activerecord/lib\n\nThe current code base is not uniform. After some discussion,\nwe have chosen to go with double quotes by default.",
   :tree=>
    {:sha=>"7a83cce62195f7b20afea6d6a8873b953d25cb84",
     :url=>
      "https://api.github.com/repos/rails/rails/git/trees/7a83cce62195f7b20afea6d6a8873b953d25cb84"},
   :url=>
    "https://api.github.com/repos/rails/rails/git/commits/4df2b779ddfcb27761c71e00e2b241bfa06a0950",
   :comment_count=>0},
 :url=>
  "https://api.github.com/repos/rails/rails/commits/4df2b779ddfcb27761c71e00e2b241bfa06a0950",
 :html_url=>
  "https://github.com/rails/rails/commit/4df2b779ddfcb27761c71e00e2b241bfa06a0950",
 :comments_url=>
  "https://api.github.com/repos/rails/rails/commits/4df2b779ddfcb27761c71e00e2b241bfa06a0950/comments"
     }
   }
 } 

这个散列有许多嵌套散列,但我想检查是否有任何嵌套散列的 :sha 值为 876239789879ab9876c8769287698769876fed

在上面的示例中,它应该返回 [:commit][:author] 哈希,因为该哈希具有 :sha 键,其值与我们正在寻找的相同。

我该怎么做?

【问题讨论】:

  • 你尝试了什么?
  • 另外,请用正确的语法发布一个完整的 Ruby 对象。
  • @EricDuminil 我将代码修改为具有正确语法的完整 Ruby 对象。
  • 不。这不是有效的语法。

标签: ruby hash key


【解决方案1】:

这是一个递归方法:

data = {a: {b: :c, d: :e}, f: {g: {h: {i: :j}}}}

def find_value_in_nested_hash(data, desired_value)
  data.values.each do |value| 
    case value
    when desired_value
      return data
    when Hash
      f = find_value_in_nested_hash(value, desired_value)
      return f if f
    end
  end
  nil
end

p find_value_in_nested_hash(data, :e)
# {b=>:c, :d=>:e}

用你的例子:

repo = { sha: '4df2b779ddfcb27761c71e00e2b241bfa06a0950',
         commit: { author:  { name: 'asasa asasa',
                              email: 'asa@asasad.com',
                              date: '2016-08-06 16:24:04 UTC',
                              sha: '876239789879ab9876c8769287698769876fed' },
                   committer:  { name: 'asasa asasa',
                                 email: 'asa@asasad.com',
                                 date: '2016-08-06 16:26:45 UTC' },
                   message:  "applies new string literal convention in activerecord/lib\n\nThe current code base is not uniform. After some discussion,\nwe have chosen to go with double quotes by default.",
                   tree:  { sha: '7a83cce62195f7b20afea6d6a8873b953d25cb84',
                            url:  'https://api.github.com/repos/rails/rails/git/trees/7a83cce62195f7b20afea6d6a8873b953d25cb84' },
                   url:  'https://api.github.com/repos/rails/rails/git/commits/4df2b779ddfcb27761c71e00e2b241bfa06a0950',
                   comment_count: 0 },
         url:  'https://api.github.com/repos/rails/rails/commits/4df2b779ddfcb27761c71e00e2b241bfa06a0950',
         html_url:  'https://github.com/rails/rails/commit/4df2b779ddfcb27761c71e00e2b241bfa06a0950',
         comments_url:  'https://api.github.com/repos/rails/rails/commits/4df2b779ddfcb27761c71e00e2b241bfa06a0950/comments' }

p find_value_in_nested_hash(repo, '876239789879ab9876c8769287698769876fed')
#=> {:name=>"asasa asasa", :email=>"asa@asasad.com", :date=>"2016-08-06 16:24:04 UTC", :sha=>"876239789879ab9876c8769287698769876fed"}

【讨论】:

  • 自动投票,因为递归,唯一的缺点是它只找到第一次出现
猜你喜欢
  • 2013-02-08
  • 1970-01-01
  • 1970-01-01
  • 2017-08-02
  • 2018-09-10
  • 2014-10-17
  • 1970-01-01
  • 1970-01-01
  • 2016-06-27
相关资源
最近更新 更多