【问题标题】:Ruby - How to iterate over hash of hashes with array & non-array valuesRuby - 如何使用数组和非数组值迭代散列的散列
【发布时间】:2014-08-31 20:19:44
【问题描述】:

我有以下哈希:

{
  "subtype"=>"example subtype",
  "contributors"=> {
    "Concept"=>["Example Contributor", "Example Contributor"],
    "Editor"=>["Example Contributor", "Example Contributor"],
    "Photographer"=>["Example"]
   },
   "publisher"=>"Example Publisher",
   "language"=>"Example Language",
   "dimensions"=>"Example Dimensions"
}

在哪里可以看到它是散列的散列,有的有字符串值,有的有数组值。我想知道如何遍历这个数组,以便获得以下输出,例如 html:

<h3>example subtype</h3>

<h3>Concept</h3>
<p>Example Contributor, Example Contributor</p>

<h3>Editor</h3>
<p>Example Contributor, Example Contributor</p>

<h3>Photographer</h3>
<p>Example</p>

<h3>Publisher</h3>
<p>Example Publisher</p>

<h3>Language</h3>
<p>Example Language</p>

<h3>Dimensions</h3>
<p>Example Dimensions</p>

到目前为止,我正在尝试遍历数组,因此遵循this answer (haml):

- object_details.each do |key, value|
  %h3= key
  - value.each do |v|
    %p= v

作为第一项当然会立即失败,subtype 没有方法 each 因为它不是数组。

我会手动获取每个值,但如果值存在或不存在,哈希值可能会改变(例如,发布者或语言可能并不总是存在于哈希值中)

除了手动检查每个哈希是否存在之外,是否有一种智能的方法来遍历此哈希?

【问题讨论】:

  • 您可以检查value 的类型,只有在它是哈希/数组时才进行迭代。否则只显示字符串。这样就足够了。
  • @matov 啊-我应该使用.class吗?我试试看
  • 你也可以使用value.kind_of?(Array),或者只使用.class

标签: ruby arrays hash


【解决方案1】:

正如@dax 提到的,也许更干净:

- object_details.each do |key, value|
  %h3= key
  %p= Array(value).join(', ')

希望对你有帮助

更正!我没有看到嵌套哈希。你可以做这样的事情(在一个助手中)

   def headers_and_paragraphs(hash)
     hash.each do |k, v|
       if v.kind_of?(Hash)
         headers_and_paragraphs(v)
       else
         puts "h3: #{k}" # Replace that with content_tag or something similar
         puts "p: #{Array(v).join(', ')}" # Replace that with content_tag or something similar
       end
     end
   end

【讨论】:

    【解决方案2】:

    你已经接近了。试试这个:

    - object_details.each do |key, value|
      %h3= key
      - if value.kind_of?(Array)
        -value.each do |v|
          %p= v
      - else
        %p= v
    

    【讨论】:

    • 还需要检查value.kind_of?(Hash)
    • @SomeGuy 在这种情况下,只有来自问题的数据,对 Array 的测试就足够了。 (请注意,OP 只希望遍历 contributors 子哈希)但是,感谢您在我的 - 已删除 - 答案下方的评论.. 这里不再有意义了,因为这个已经可以做到了.. +1跨度>
    【解决方案3】:
    $modifiedContent = []
    def convert(hash)
       hash.each do |key, value|
          unless (value.kind_of?(Hash))
             unless (value.is_a? String and hash.first.first.eql? key and hash.first.last.eql? value)
                $modifiedContent << "<h3>#{key}</h3>"
                $modifiedContent << "<p>#{Array(value).join(', ')}</p>"
             else
                $modifiedContent << "<p>#{value}</p>"
             end
          else
             convert(value)
          end
          $modifiedContent << ""
       end
    end
    
    myHash = {
      "subtype"=>"example subtype",
      "contributors"=> {
        "Concept"=>["Example Contributor", "Example Contributor"],
        "Editor"=>["Example Contributor", "Example Contributor"],
        "Photographer"=>["Example"]
       },
       "publisher"=>"Example Publisher",
       "language"=>"Example Language",
       "dimensions"=>"Example Dimensions"
    }
    
    convert(myHash)
    puts $modifiedContent
    

    【讨论】:

      猜你喜欢
      • 2012-12-01
      • 2011-05-01
      • 2018-12-28
      • 1970-01-01
      • 2011-07-24
      • 1970-01-01
      • 2012-08-03
      • 2011-07-26
      • 2010-12-04
      相关资源
      最近更新 更多