简体   繁体   English

将哈希值插入到字符串中

[英]Inserting hash values into string

I have an array of hashes in the format 我有一个格式的哈希数组

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

etc.. 等等..

I am trying to insert this output into a string that then needs to be inserted into html. 我试图将此输出插入一个字符串,然后需要插入到HTML中。 I currently have this 我现在有这个

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

I know that this probably isn't the best way to get the values but I can't figure out any other way, but my major problem is that when I try this I get this error: 我知道这可能不是获取值的最佳方法,但我无法弄清楚任何其他方式,但我的主要问题是,当我尝试这个时,我得到这个错误:

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

Is there any way to insert the values from each hash side by side into the string? 有没有办法将每个哈希值并排插入字符串?

PS I used name and year for readability. PS我使用名字和年份来提高可读性。 I know #{x.values[0]} #{x.values[1]} is the correct way to format this. 我知道#{x.values [0]}#{x.values [1]}是格式化的正确方法。

In Ruby, String#+ does not implicitly convert the right operand to a string. 在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"

Also, in the post albums.each .. do returns the initial array (albums) object, but that is still wrong as the result of the block is discarded (use Array.each for performing side-effects). 此外,在post albums.each .. do返回初始数组(专辑)对象,但这仍然是错误的,因为该块的结果被丢弃(使用Array.each执行副作用)。 Instead, use albums.map .. do (or albums.collect .. do ) to collect/use the block results. 相反,使用albums.map .. do (或albums.collect .. do )来收集/使用块结果。

This is simple code showing how to do it: 这是显示如何执行此操作的简单代码:

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)

Which outputs: 哪个输出:

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

In real life I'd use ERB or HAML to generate the HTML. 在现实生活中,我会使用ERBHAML来生成HTML。 They're great templating tools. 它们是很棒的模板工具。

Other ways of writing: 其他写作方式:

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

Are: 是:

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

or: 要么:

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

I don't recommend using album.values by itself because it relies on the order of insertion into the album hash. 我不建议album.values使用album.values ,因为它依赖于插入album哈希的顺序。 In the future, if you modify the hash by putting something into it in a different order while maintaining the code, the values order will change, breaking it in a way that might not be obvious. 将来,如果您通过在维护代码的同时以不同的顺序放入哈希值来修改哈希values ,则values顺序将发生变化,以一种可能不明显的方式打破它。

Instead, use one of these ways of accessing the values to always explicitely get the value associated with the key. 相反,使用这些访问值的方法之一总是明确地获得与密钥关联的值。 That's part of programming defensively. 这是防御性编程的一部分。

albums.each is not doing what you think it is. albums.each并没有按照你的想法行事。 I get the impression that you want it to append something along these lines into your string. 我得到的印象是你希望它沿着这些线附加到你的字符串中。

name is: Sgt. 名字是:Sgt。 Pepper's Lonely Hearts Club Band year is: 1967 name is: Are you Experienced? 佩珀的Lonely Hearts Club乐队年份是:1967年的名字是:你有经验吗? year is: 1967 年是:1967年

What actually happens is effectively nothing. 实际发生的事实上没什么。 You have an expression inside a .each which is the same as a for loop that is simultaneously trying to append the albums array into your string. 在.each中有一个表达式,它与同时尝试将相册数组附加到字符串中的for循环相同。 Hence the can't convert Array into String error. 因此无法将Array转换为String错误。

The easiest way to achieve what you want would be to get the string up front and then append it into your string. 实现您想要的最简单方法是将字符串放在前面,然后将其附加到字符串中。 Something akin to this. 类似于此的东西。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM