通过键名称从 ruby​​ 中的多维哈希中提取特定值

发布于 2024-08-21 04:22:16 字数 338 浏览 6 评论 0原文

假设我有一个多维哈希,并且在其中一个子哈希中我有一个 key=>value 对,我需要通过键检索它。我该怎么做?

示例散列:

h={:x=>1,:y=>2,:z=>{:a=>{:k=>"needle"}}}
h={:k=>"needle"}

键总是:k,我需要得到“needle”

我注意到ruby 1.8中没有用于散列的“展平”函数,但如果它在那里,我想我会做

h.flatten[:k]

我想象的我需要为此编写一个递归函数吗?

谢谢

let's say i have a multidimensional hash, and in one of the subhashes i have a key=>value pair which i need to retrieve by key. how can i do it?

example hashes:

h={:x=>1,:y=>2,:z=>{:a=>{:k=>"needle"}}}
h={:k=>"needle"}

key is always :k, and i need to get "needle"

i noticed that there is no "flatten" function for hashes in ruby 1.8, but if it'd be there, i imagine i'd just do

h.flatten[:k]

i imagine i need to write a recursive function for that?

thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

浮世清欢 2024-08-28 04:22:16

您始终可以编写自己的特定于任务的 Hash 扩展,它会为您完成肮脏的工作:

class Hash
  def recursive_find_by_key(key)
    # Create a stack of hashes to search through for the needle which
    # is initially this hash
    stack = [ self ]

    # So long as there are more haystacks to search...
    while (to_search = stack.pop)
      # ...keep searching for this particular key...
      to_search.each do |k, v|
        # ...and return the corresponding value if it is found.
        return v if (k == key)

        # If this value can be recursively searched...
        if (v.respond_to?(:recursive_find_by_key))
          # ...push that on to the list of places to search.
          stack << v
        end
      end
    end
  end
end

您可以非常简单地使用它:

h={:x=>1,:y=>2,:z=>{:a=>{:k=>"needle"}}}

puts h.recursive_find_by_key(:k).inspect
# => "needle"

h={:k=>"needle"}

puts h.recursive_find_by_key(:k).inspect
# => "needle"

puts h.recursive_find_by_key(:foo).inspect
# => nil

You can always write your own mission-specific extension to Hash which does the dirty work for you:

class Hash
  def recursive_find_by_key(key)
    # Create a stack of hashes to search through for the needle which
    # is initially this hash
    stack = [ self ]

    # So long as there are more haystacks to search...
    while (to_search = stack.pop)
      # ...keep searching for this particular key...
      to_search.each do |k, v|
        # ...and return the corresponding value if it is found.
        return v if (k == key)

        # If this value can be recursively searched...
        if (v.respond_to?(:recursive_find_by_key))
          # ...push that on to the list of places to search.
          stack << v
        end
      end
    end
  end
end

You can use this quite simply:

h={:x=>1,:y=>2,:z=>{:a=>{:k=>"needle"}}}

puts h.recursive_find_by_key(:k).inspect
# => "needle"

h={:k=>"needle"}

puts h.recursive_find_by_key(:k).inspect
# => "needle"

puts h.recursive_find_by_key(:foo).inspect
# => nil
雪花飘飘的天空 2024-08-28 04:22:16

如果您只需要获取键值,但不知道键有多深,请使用此代码片段

def find_tag_val(hash, tag)
  hash.map do |k, v|
    return v if k.to_sym == tag
    vr = find_tag_val(v, tag) if v.kind_of?(Hash)
    return vr if vr
  end
  nil #othervice
end 

h = {message: { key: 'val'}}
find_tag_val(h, :key) #=> 'val'

If you need simply to fetch key value, but don't know how deep the key is, use this snippet

def find_tag_val(hash, tag)
  hash.map do |k, v|
    return v if k.to_sym == tag
    vr = find_tag_val(v, tag) if v.kind_of?(Hash)
    return vr if vr
  end
  nil #othervice
end 

h = {message: { key: 'val'}}
find_tag_val(h, :key) #=> 'val'
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文