[ruby-list:45891] Re: how to extract nested table

From: Shinya Kawaji <kawaji@...>
Date: 2009-02-25 18:07:25 UTC
List: ruby-list #45891
かわじ、です。


> 図解.
> 
>   |         |         |        "c"         |
>   |   "a"   |   "b"   | "ca" | "cb" | "cc" |
> --+---------+---------+------+------+------+
>   |         |         |"ca11"|"cb11"|"cc11"|
> 1 |   "a1"  |   "b1"  |"ca12"|"cb12"|"cc12"|
>   |         |         |"ca13"|"cb13"|"cc13"|
> --+---------+---------+------+------+------+
>   :         :         :      :      :      :

これは具体的には、HTMLではどう書くのでしょう。
2例ほど考えたので後で載せますが、それはともかく、


> [{"a" => "a1", "b" => "b1", 
>   "c" => [{"ca" => "ca11", "cb" => "cb11", "cc" => "cc11"}, 
>           {"ca" => "ca12", "cb" => "cb12", "cc" => "cc12"}, 
> 	  {"ca" => "ca13", "cb" => "cb13", "cc" => "cc13"}]}, 
>  {"a" => "a2", "b" => "b2", .....
> 
> のようなデータを引っ張ってくるためにメソッドに構造を知らせるために
> 配列を使うと ["a", "b", ["ca", "cb", "cc"]] となり, "c" のような枝
> 部分の見出しを知らせることが出来ません.一方でハッシュを使って構造を
> 知らせようとすると,
> {"a" => nil, "b" => nil, "c" => {"ca" => nil, "cb" => nil, "cc" => nil}}
> といった感じになりましょうが,ハッシュなので順序が確保できません.

「見出し」部分は全て配列の入れ子にして、位置を特定するようにすればいかが
でしょう。

  # キー部分の配列
  keys = ['a', 'b', ['c', ['ca', 'cb', 'cc']]]

別途、データの中身も全て配列の入れ子にして、

  # データの中身
  vals = [
    ['a1', 'b1', [
      ['ca11', 'cb11', 'cc11'],
      ['ca12', 'cb12', 'cc12'],
      ['ca13', 'cb13', 'cc13'],
    ]],
  ]

それから最終的に、

def set(table, key, val)
  if key.kind_of?(Array) and val.kind_of?(Array)
    table[key.first] = []
    val.each_with_index{|row, row_idx|
      t = table[key.first][row_idx] = {}
      key.last.each_with_index{|k, key_idx|
        set(t, k, row[key_idx])
      }
    }
  elsif key.kind_of?(String) and val.kind_of?(String)
    table[key] = val
  else
    raise ArgumentError, "key: #{key.inspect}, val: #{val.inspect}"
  end
end

table = vals.collect{|row|
  t = {}
  row.each_with_index{|cell, i|
    set(t, keys[i], cell)
  }
  t
}

とします。set関数はかなりベタな書き方なので、もっと美しく出来るでしょう。

こういった感じで、解決になるでしょうか。


以下、おまけ。

■考えたHTML その1

<table><thead><tr>
  <th></th>
  <td>a</td>
  <td>b</td>
  <td>
    <table><thead><tr>
      <td>c</td>
    </tr></thead><tbody><tr>
      <td>ca</td>
      <td>cb</td>
      <td>cc</td>
    </tr></tbody></table>
  </td>
</tr></thead><tbody><tr>
  <th>1</th>
  <td>a1</td>
  <td>b1</td>
  <td>
    <table><tbody><tr>
      <td>ca11</td>
      <td>cb11</td>
      <td>cc11</td>
    </tr><tr>
      <td>ca12</td>
      <td>cb12</td>
      <td>cc12</td>
    </tr><tr>
      <td>ca13</td>
      <td>cb13</td>
      <td>cc13</td>
    </tr></tbody></table>
  </td>
</tr></tbody></table>


■考えたHTML その2

<table><thead><tr>
  <th rowspan="2"></th>
  <td rowspan="2">a</td>
  <td rowspan="2">b</td>
  <td colspan="3">c</td>
</tr><tr>
  <td>ca</td>
  <td>cb</td>
  <td>cc</td>
</tr></thead><tbody><tr>
  <th>1</th>
  <td rowspan="3">a1</td>
  <td rowspan="3">b1</td>
  <td>ca11</td>
  <td>cb11</td>
  <td>cc11</td>
</tr><tr>
  <td>ca12</td>
  <td>cb12</td>
  <td>cc12</td>
</tr><tr>
  <td>ca13</td>
  <td>cb13</td>
  <td>cc13</td>
</tr></tbody></table>



In This Thread

Prev Next