2017-03-09 102 views
-2

说我有这样的哈希:如何在嵌套散列中搜索特定键的值?

[82] pry(main)> commit2 
=> {:sha=>"4df2b779ddfcb27761c71e00e2b241bfa06a0950", 
:commit=> 
    {:author=> 
    {:name=>"asasa asasa", 
    :email=>"[email protected]", 
    :date=>2016-08-06 16:24:04 UTC, 
    :sha=> "876239789879ab9876c8769287698769876fed"}, 
    :committer=> 
    {:name=>"asasa asasa", 
    :email=>"[email protected]", 
    :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" 
    } 
    } 
} 

该散列有很多嵌套的哈希值,但我要检查,看看是否有任何嵌套的散列有876239789879ab9876c8769287698769876fed一个:sha值。

在上面的例子中,它应该返回[:commit][:author]散列,因为那个有:sha的键值与我们正在寻找的键相同。

我该怎么做?

+0

那你试试? –

+0

此外,请使用正确的语法发布完整的Ruby对象。 –

+0

@EricDuminil我修改了它的代码,使它成为一个完整的Ruby对象,语法正确。 – marcamillion

回答

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: '[email protected]', 
           date: '2016-08-06 16:24:04 UTC', 
           sha: '876239789879ab9876c8769287698769876fed' }, 
        committer: { name: 'asasa asasa', 
           email: '[email protected]', 
           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=>"[email protected]", :date=>"2016-08-06 16:24:04 UTC", :sha=>"876239789879ab9876c8769287698769876fed"}