Hashes of Hashes Idiom in Ruby?

后端 未结 3 858
旧巷少年郎
旧巷少年郎 2020-12-12 20:58

Creating hashes of hashes in Ruby allows for convenient two (or more) dimensional lookups. However, when inserting one must always check if the first index already exists i

相关标签:
3条回答
  • 2020-12-12 21:21

    Autovivification, as it's called, is both a blessing and a curse. The trouble can be that if you "look" at a value before it's defined, you're stuck with this empty hash in the slot and you would need to prune it off later.

    If you don't mind a bit of anarchy, you can always just jam in or-equals style declarations which will allow you to construct the expected structure as you query it:

    ((h ||= { })['w'] ||= { })['z']
    
    0 讨论(0)
  • 2020-12-12 21:38

    You can pass the Hash.new function a block that is executed to yield a default value in case the queried value doesn't exist yet:

    h = Hash.new { |h, k| h[k] = Hash.new }
    

    Of course, this can be done recursively. There's an article explaining the details.

    For the sake of completeness, here's the solution from the article for arbitrary depth hashes:

    hash = Hash.new(&(p = lambda{|h, k| h[k] = Hash.new(&p)}))
    

    The person to originally come up with this solution is Kent Sibilev.

    0 讨论(0)
  • 2020-12-12 21:41
    require 'xkeys'
    h = {}.extend XKeys::Hash
    
    h['x', 'y'] = value_to_insert
    looked_up_value = h['w', 'z'] # nil
    
    h[:foo, :bar, :baz, :else => 0] += 1
    
    0 讨论(0)
提交回复
热议问题