[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>