【问题标题】:Looping through ruby hashes循环遍历 ruby​​ 哈希
【发布时间】:2016-10-26 01:55:18
【问题描述】:

我正在尝试关注this example,但是当我找不到像他那样遍历哈希的方法时:

...  
platforms = {
  'MyOS' => {
    'package' => 'package',
    'versions' => ['1.0', '2.0','3.0']
  }
}
...
platforms.each do |platform, (package, versions)|
  versions.each do |version|
    context "On #{platform} #{version}" do
    before do
      Fauxhai.mock(platform: platform, version: version)
    end

    let(:chef_run) { ChefSpec::ChefRunner.new.converge('cookbook::recipe') }

    it "Installs the package" do
      chef_run.should install_package package
    end
  end
end
...

我收到以下错误:

/path/file.rb:XX:in `block (2 levels) in <top (required)>': undefined method `each' for nil:NilClass (NoMethodError)

由于某种原因,|a, (b,c)| 不起作用,圆括号被忽略。

似乎platform 包含(如预期)'MyOS',但迭代器 package 等于 '{"package"=>"package", "versions"=> ["1.0", "2.0", "3.0"]}'versions 为空。

我期待以下内容:

platform = "MyOS"
package = "package"
versions = ["1.0", "2.0", "3.0"]

所以我可以在循环浏览平台版本时访问包名称。

【问题讨论】:

    标签: ruby


    【解决方案1】:

    试试这个。每个平台都有一个名称和一组属性。每个属性都有一个名称和一个值。

    platforms.each do |name, platform|
      puts "platform = #{name}"
      platform.each do |attribute, value|
        puts "#{attribute} = #{value}"
      end
    end
    

    【讨论】:

    • 这接近我需要的,但是我需要能够访问列表中每个版本的包名称。以这种方式循环,我只能在第一次迭代时访问包名,我认为将此值存储在外部变量上是不合适的。
    • 我想根据需要复制您提供的内容。如果有什么不同,请更新问题,我会更改答案。
    • 在我的示例中,您的版本位于 platform['versions']
    • 这正是我要找的,谢谢指出。
    • 我很高兴先生 :) 我没有意识到你想要那个。
    【解决方案2】:

    如果我们有

    platforms = { 'MyOS' => { 'package'=>'package', 'versions' => ['1.0', '2.0','3.0'] } }
    

    platforms.each do |platform, (package, versions)|...
    

    platforms 的第一个(也是唯一一个)元素(键值对)传递给块

    platforms.first
      #=> ["MyOS", {"package"=>"package", "versions"=>["1.0", "2.0", "3.0"]}]
    

    您正在将块变量分配给该值:

    platform, (package, versions) = ["MyOS", {"package"=>"package",
      "versions"=>["1.0", "2.0", "3.0"]}]
    

    通过并行赋值(有时称为多重赋值),Ruby 获得:

    platform          #=> "MyOS" 
    package, version  #=> {"package"=>"package", "versions"=>["1.0", "2.0", "3.0"]}
    

    然后通过再次应用并行赋值,她得到:

    package           #=> {"package"=>"package", "versions"=>["1.0", "2.0", "3.0"]}
    versions          #=> nil 
    

    这不是你想要的。考虑到platform.first 只包含两个元素,这个结果也不应该令人惊讶。相反,您需要两个块变量,platform, h 以便

    platform, h = ["MyOS", {"package"=>"package", "versions"=>["1.0", "2.0", "3.0"]}]
    platform #=> "MyOS" 
    h #=> {"package"=>"package", "versions"=>["1.0", "2.0", "3.0"]}
    

    然后你需要在区块内操作哈希h

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-08-20
      • 2013-11-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多