0

我有一个哈希数组的格式

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

ETC..

我正在尝试将此输出插入到一个字符串中,然后需要将其插入到 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>

在现实生活中,我会使用ERBHAML来生成 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 循环相同。因此无法将 Array 转换为 String 错误。

实现您想要的最简单的方法是将字符串放在前面,然后将其附加到您的字符串中。类似于此的东西。

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 回答