【问题标题】:Why is the size of this Hash of arrays 0?为什么这个数组 Hash 的大小为 0?
【发布时间】:2014-10-31 11:58:22
【问题描述】:

这是我的代码:

def mainFunction    
    @notes=Hash.new(Array.new)
    @notes["First"].push(true)
    @notes["First"].push(false)
    @notes["First"].push(true)
    @notes["Second"].push(true)
    output @notes.size.to_s
end

为什么输出是0?它应该是2,因为notes 有两个键,"First""Second"

【问题讨论】:

  • 在您的示例中,没有要推送的键。您必须首先初始化指向像 @notes = {"First" => []} 这样的数组的键,然后当您执行 @notes["First"].push(true) 时,它会起作用。
  • How to assign hash[“a”][“b”]= “c” if hash[“a”] doesn't exist? 也类似,或者至少答案应该有助于解决问题。
  • 您的问题类似于this one。您可能希望查看那里的答案以获得更多见解。如果您选择不使用Hash.new {|h, k| h[k] = []},您可能会考虑是否要使用@notes=Hash.new(Array.new) 而不是@notes=Hash.new(Array.new)。对于后者,所有键共享同一个数组;对于后者,每个都有自己的数组。不要忘记选择一个答案(如果您发现有任何帮助)。

标签: ruby arrays size


【解决方案1】:

在第一次访问时初始化 Hash 值(即推送到尚不存在的键值)时,您需要在请求时在 Hash 上设置键。

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

作为参考,请在 ruby​​ repl 中按照您的方式初始化 Hash 中查看以下结果

irb(main):063:0> @notes = Hash.new(Array.new)
=> {}
irb(main):064:0> @notes[:foo].push(true)
=> [true]
irb(main):065:0> @notes.has_key?(:foo)
=> false
irb(main):066:0> puts @notes.size
=> 0

现在是正确的方法。

irb(main):067:0> @notes = Hash.new {|h, k| h[k] = []}
=> {}
irb(main):068:0> @notes[:foo].push(true)
=> [true]
irb(main):069:0> @notes.has_key?(:foo)
=> true
irb(main):070:0> @notes.size
=> 1

【讨论】:

  • Deefour,很抱歉这样与您联系,但我不知道如何与您取得联系。我注意到您投票决定将我的问题 stackoverflow.com/questions/26743387/… 搁置。它现在已经被编辑得更清楚了,我急需一个答案。请考虑撤回您的投票,以便我尽快悬赏。
【解决方案2】:

以下声明:

@notes=Hash.new(Array.new)

使用默认值创建一个散列:Array.new。当您使用未知键访问哈希时,您将收到此默认值。

您的其他声明会更改该默认数组:

@notes["First"].push(true)

这会将true 添加到默认(空)数组中。

需要先初始化"First"数组:

@notes["First"] = []

然后你可以添加值:

@notes["First"].push(true)

或更多“红宝石”:

@notes["First"] << true

现在的尺寸是:

@notes.size # => 1

【讨论】:

  • 不错! &lt;&lt; true 怎么称呼?
  • &lt;&lt;被称为Append,见the documentation
【解决方案3】:

@notes = Hash.new(Array.new) 将所有元素的默认值设置为同一个数组。由于@notes 不包含键“First”,因此它返回该默认值,并且 .push 添加到它的末尾。但是密钥尚未添加到哈希中。其他推送添加到相同默认数组的末尾。

【讨论】:

    【解决方案4】:

    阅读this Hash.new(obj)。它指出:

    如果指定了 obj,则此单个对象将用于所有默认值 价值观。

    因此,当您这样做时:@notes=Hash.new(Array.new)。默认对象将是一个数组。

    @notes.default # => []
    @notes['First'].push(true)
    @notes.default # => [true]
    @notes['First'].push(false)
    @notes.default # => [true, false]
    

    但是,@notes 中不会有任何条目作为键,当然您可以通过提供任何键(可能存在也可能不存在)来访问这些值,如下所示:

    @notes['unknown_key'] #=> [true, false]
    

    【讨论】:

      【解决方案5】:

      Hash.new(object) 方法调用表单只返回object 作为默认值,但不更新哈希。

      您正在寻找可以进行更新的块状表单:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-06-04
        • 2021-07-11
        • 1970-01-01
        • 2013-02-06
        • 2021-02-17
        • 2015-02-13
        • 2019-04-28
        • 1970-01-01
        相关资源
        最近更新 更多