0

たとえば、Rubyハッシュがあります。

{"monkeys"=> {"hamburgers" => ["love", "eat"],
              "boulders" => ["hate", "throw"]},
 "stonemasons" => {"boulders" = > ["love", "use"],
                   "vandals" => ["hate", "sue"]}
}

ほぼすべてのレベルの深さを持つことができます (ハッシュ内にハッシュを何度でも入れることができます)。終了値として常に配列があります。

Railsを使用せずに、できれば標準ライブラリのみを使用して、以下のようなHTMLテーブルに解析するにはどうすればよいですか?

<table>
  <tr>
    <th rowspan="2">monkeys</th>
    <th>hamburgers</th>
    <td>love</td>
    <td>eat</td>
  </tr>
  <tr>
    <th>boulders</th>
    <td>hate</td>
    <td>throw</td>
  </tr>
  <tr>
    <th rowspan="2">stonemasons</th>
    <th>boulders</th>
    <td>love</td>
    <td>use</td>
  </tr>
  <tr>
    <th>vandals</th>
    <td>hate</td>
    <td>sue</td>
  </tr>
</table>
4

1 に答える 1

1

それはそれを行う必要があります:

h = {"monkeys"     => {"hamburgers" => ["love", "eat"],
                       "boulders"   => ["hate", "throw"]},
     "stonemasons" => {"boulders"   => ["love", "use"],
                       "vandals"    => ["hate", "sue"]}}


def parse_data(html, data, new_line = true)

  klass = data.class

  # Use the class to know if we need to create TH or TD
  case
  when klass == Hash
    data.each do |key, value|

      # Start a new row
      if new_line
        html << '<tr>'
        new_line = false
      end

      # Check if we need to use a rowspan
      if value.class == Array || value.count == 1
        html << "<th>#{key}</th>"
      else
        html << "<th rowspan=\"#{value.count}\">#{key}</th>"
      end

      # Parse the content of the hash (recursive)
      html, new_line = parse_data(html, value, new_line)
    end
  when klass = Array
    data.each do |item|
      html << "<td>#{item}</td>"
    end

    # We end the row and flag that we need to start a new one
    # if there is anymore data
    html << '</tr>'
    new_line = true
  end

  return html, new_line
end

html = '<table>'
html, new_line = parse_data(html, h)
html << '</table>'

puts html

出力:

<table>
  <tr>
    <th rowspan="2">monkeys</th>
    <th>hamburgers</th>
    <td>love</td>
    <td>eat</td>
  </tr>
  <tr>
    <th>boulders</th>
    <td>hate</td>
    <td>throw</td>
  </tr>
  <tr>
    <th rowspan="2">stonemasons</th>
    <th>boulders</th>
    <td>love</td>
    <td>use</td>
  </tr>
  <tr>
    <th>vandals</th>
    <td>hate</td>
    <td>sue</td>
  </tr>
</table>
于 2013-10-23T09:36:43.343 に答える