简体   繁体   English

Ruby-如何遍历具有数组和非数组值的哈希哈希

[英]Ruby - How to iterate over hash of hashes with array & non-array values

I have the following hash: 我有以下哈希值:

{
  "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"
}

Where one can see that it is a hash of hashes, and some have string values and some have array values. 可以看到它是哈希值的哈希值,有些具有字符串值,有些具有数组值。 I was wondering how I can iterate through this array so that I could have the following output, for example html: 我想知道如何遍历此数组,以便获得以下输出,例如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>

So far, I am trying to iterate through the array so following this answer (haml): 到目前为止,我正在尝试遍历数组,因此请遵循以下答案 (haml):

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

Which of course fails immediately as the first item, subtype has no method each as it is not an array. 当然,哪一个作为第一项subtype立即失败,因为它不是数组,所以each subtype都没有方法。

I would take each value manually, but the hash may change if values are present or absent (for example, publisher or language may not always be present in the hash) 我会手动获取每个值,但是如果值存在或不存在,则哈希值可能会发生变化(例如,哈希值中可能不总是存在发布者或语言)

Is there a smart way to iterate through this hash other than checking for the presence of each hash manually? 除了手动检查每个哈希的存在之外,是否有一种聪明的方法来遍历此哈希?

As @dax mention, and maybe cleaner like: 正如@dax所提到的,也许更干净:

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

I hope that helps 希望对您有所帮助

Correction! 更正! I didn't see the nested Hash. 我没有看到嵌套的哈希。 You can do something like this(in a helper) 您可以做这样的事情(在助手中)

   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

you're close. 你近了。 try this: 尝试这个:

- object_details.each do |key, value|
  %h3= key
  - if value.kind_of?(Array)
    -value.each do |v|
      %p= v
  - else
    %p= v
$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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM