【问题标题】:Ruby Hash.new weirdness [duplicate]Ruby Hash.new 怪异[重复]
【发布时间】:2012-10-02 01:21:00
【问题描述】:

可能重复:
Strange ruby behavior when using Hash.new([])

这是一个简单的问题,因为我已经不知所措了。

为什么会这样:

1.9.3-p194 :001 > h = Hash.new([])
 => {} 
1.9.3-p194 :002 > h[:key1] << "Ruby"
 => ["Ruby"] 
1.9.3-p194 :003 > h
 => {} 
1.9.3-p194 :004 > h.keys
 => [] 
1.9.3-p194 :005 > h[:key1]
 => ["Ruby"] 

【问题讨论】:

    标签: ruby hashmap


    【解决方案1】:

    此构造Hash.new([]) 返回默认值,但此值不是哈希的初始化值。您正在尝试使用哈希,假设默认值是哈希的一部分。

    您需要的是在某个键处初始化散列的构造:

    hash = Hash.new { |h,k| h[k] = [] } 
    
    hash[:key1] << "Ruby"
    
    hash #=> {:key1=>["Ruby"]}
    

    【讨论】:

    • 这是关于 Ruby 的事情之一,我认为它应该可以工作。感谢您的回答。如果允许,我会在 5 分钟内接受!
    【解决方案2】:

    查看Hash.new的文档

    new → new_hash
    new(obj) → new_hash
    new {|hash, key| block } → new_hash
    

    如果此哈希随后被不对应于哈希条目的键访问,则返回的值取决于用于创建哈希的 new 的样式。

    1. 在第一种形式中,访问返回 nil。
    2. 如果指定了 obj,则此单个对象将用于所有默认值。
    3. 如果指定了一个块,它将使用哈希对象和键调用,并且应该返回默认值。如果需要,区块有责任将值存储在哈希中。

    irb(main):015:0> h[:abc] # ["Ruby"]
    

    所以["Ruby"] 如果没有找到键,则作为默认值返回,而不是 nil。

    【讨论】:

    • 我脑子里突然闪过一个光亮的时刻。这实际上解释了我认为这是错误的。谢谢!
    • 感谢您正确解释这一点。其他答案只是反映了我的观察,并没有真正解释为什么
    【解决方案3】:

    您实际上没有使用h[:keys] &lt;&lt; "Ruby" 设置值。您只需为返回的未找到键的默认数组添加一个值。所以没有创建密钥。

    这样写就好了:

    h = Hash.new([])
    h[:keys1] = []
    h[:keys1] << "Ruby"
    

    【讨论】:

    • 看,这很奇怪,因为当我评估 h[:key1] 时,它会返回我期望的结果。
    • 这是默认值,它会在任何缺失的键上返回相同的数组。
    【解决方案4】:

    我不得不承认,当我阅读您的问题时,这也让我感到困惑。我看了一下docs,但它变得很清楚。

    如果指定了obj,则这个单一对象将用于所有默认值

    所以你实际做的是修改这个用于默认值的单个数组对象,而无需分配给键!

    检查一下:

    h = Hash.new([])
    
    h[:x] << 'x'
    # => ['x']
    
    h
    # => {}
    
    h[:y]
    # => ['x']  # CRAZY TIMES
    

    所以你需要以某种方式进行分配 - h[:x] += ['x'] 可能是要走的路。

    【讨论】:

    • 你的回答让我笑了!我是否认为这不是明确的行为?
    • 哈哈很高兴听到它。我想说这很清楚(在这方面,一旦您阅读了文档,就很明显了),但可能并不直观(因为您需要阅读文档才能解决问题!)。
    【解决方案5】:

    当您创建这样的哈希时:

    h = Hash.new([])       
    

    这意味着,每当使用尚未定义的键访问哈希时,它都会返回:

    []
    

    现在当你这样做时:

    h[:key1] << "Ruby"
    

    h[:key1] 已返回 []"Ruby" 被推送到其中,导致 ["Ruby"] 作为输出,因为这是返回的最后一个对象。这也被设置为使用未定义键访问“h”时返回的默认值。 因此,当你这样做时:

    h[:key1] or h[:key2] or h[:whatever]
    

    你会得到

    "Ruby"
    

    作为输出。 希望这会有所帮助。

    【讨论】:

    • 非常好的答案!谢谢:-)
    • 没问题的人!你也帮助我学习了……我必须阅读文档才能弄清楚发生了什么。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-29
    • 1970-01-01
    • 2021-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多