0

形式のハッシュの配列があります

albums = [ {name: "Sgt. Pepper's Lonely Hearts Club Band", year: "1967" }, 
           { name: "Are You Experienced?", year: "1967" } 
         ]

等..

この出力を、html に挿入する必要がある文字列に挿入しようとしています。私は現在これを持っています

def convert_to_html albums
  string_before = 
    "<html>
      <head>
        <title>\"Rolling Stone's ....\"</title>
      </head>
      <body>
        <table>\n" + 
        albums.each do |x| 
          "name is: #{x.values[0]} year is: #{x.values[1]}"
        end  + "
        </table>
      </body>
    </html>"
end

これはおそらく値を取得するための最良の方法ではないことはわかっていますが、他の方法はわかりませんが、これを試すと次のエラーが発生することが主な問題です。

[2013-01-27 00:16:20] ERROR TypeError: can't convert Array into String
    albums.rb:72:in `+'
    albums.rb:72:in `convert_to_html'
    albums.rb:28:in `block in render_list'
    albums.rb:26:in `open'
    albums.rb:26:in `render_list'
    albums.rb:9:in `call'

各ハッシュの値を並べて文字列に挿入する方法はありますか?

PS 読みやすくするために名前と年を使用しました。#{x.values[0]} #{x.values[1]} がこれをフォーマットする正しい方法であることはわかっています。

4

3 に答える 3

2

Rubyでは、右のオペランドを暗黙的に文字列に変換String#+しません。

# like post - oops!
> "hello " + ["world", "moon"]
=> #<TypeError: can't convert Array into String>

# valid, but .. ugly
> "hello " + ["world", "moon"].to_s
=> "hello [\"world\",\"moon\"]"

# likely desired
> "hello " + ["world", "moon"].join(" and ")
=> "hello world and moon"

また、投稿でalbums.each .. doは最初の配列(アルバム)オブジェクトが返されますが、ブロックの結果が破棄されるため、それでも間違っています(副作用を実行するにはArray.eachを使用してください)。代わりに、albums.map .. do(またはalbums.collect .. do)を使用してブロック結果を収集/使用します。

于 2013-01-27T08:02:07.880 に答える
0

これは、その方法を示す簡単なコードです。

album_list = [
  {name: "Sgt. Pepper's Lonely Hearts Club Band", year: "1967" }, 
  { name: "Are You Experienced?", year: "1967" } 
]

def convert_to_html(albums)

"<html>
  <head>
    <title>\"Rolling Stone's ....\"</title>
  </head>
  <body>
    <table>
" + albums.map { |album| 
"     <tr><td>name is: #{ album[:name] } year is: #{ album[:year] }</td></tr>"
}.join("\n") +
"
    </table>
  </body>
</html>"

end

puts convert_to_html(album_list)

どの出力:

<html>
  <head>
    <title>"Rolling Stone's ...."</title>
  </head>
  <body>
    <table>
    <tr><td>name is: Sgt. Pepper's Lonely Hearts Club Band year is: 1967</td></tr>
    <tr><td>name is: Are You Experienced? year is: 1967</td></tr>
    </table>
  </body>
</html>

実際には、ERBまたはHAMLを使用して HTML を生成します。これらは優れたテンプレート ツールです。

他の書き方:

<tr><td>name is: #{ album[:name] } year is: #{ album[:year] }</td></tr>"

は:

<tr><td>name is: %s year is: %s </td></tr>" % [ album[:name], album[:year] ] 

また:

<tr><td>name is: %s year is: %s </td></tr>" % album.values_at(:name, :year)

ハッシュalbum.valuesへの挿入順序に依存するため、単独で使用することはお勧めしません。album将来、コードを維持しながら別の順序で何かを入れてハッシュを変更すると、values順序が変更され、明らかではない方法でハッシュが壊れます。

代わりに、値にアクセスするこれらの方法のいずれかを使用して、キーに関連付けられた値を常に明示的に取得します。それは防御的なプログラミングの一部です。

于 2013-01-27T08:04:26.700 に答える
0

albums.each は、あなたが思っていることをしていません。これらの行に沿って文字列に何かを追加したいという印象を受けました。

名前は:軍曹です。Pepper's Lonely Hearts Club Band 年: 1967 年 名前: Are you Experienced? 年は: 1967

実際に起こることは事実上何もありません。.each 内に式があります。これは for ループと同じで、albums 配列を同時に文字列に追加しようとしています。したがって、配列を文字列エラーに変換できません。

目的を達成する最も簡単な方法は、文字列を前もって取得し、それを文字列に追加することです。これに似た何か。

def convert_to_html albums
append_string = ""
albums.each do |album|
  append_string += "<tr><td>name is: #{album[:name]} year is #{album[:year]} </td></tr>"
end

string_before =
  "<html>
    <head>
      <title>\"Rolling Stone's ....\"</title>
    </head>
    <body>
      <table>\n" + append_string + "
      </table>
    </body>
  </html>"
end
于 2013-01-27T08:09:49.147 に答える