简体   繁体   English

Ruby高效各回路

[英]Ruby efficient each loop

Is there a better way to write this?有没有更好的方法来写这个? markdown is a StringIO markdown是一个 StringIO

coverage_hash_arr = [
        {
          "Module": "Mobile",
          "name": "Sheila Chapman",
          "age": 21
        },
        {
          "Module": "Web",
          "name": "Hendricks Walton",
          "age": 40
        },
        {
          "Module": "Misc",
          "name": "Torres Mcdonald",
          "age": 39
        }
    ]

coverage_hash_arr.each do |the_hash|
    markdown << "------- Status on #{the_hash[:Module]} -------\n"
    the_hash.delete(:Module)
    the_hash.each {|key, value| markdown << "- #{key}: #{value} \n"} 
    markdown << "----------------------------------------------\n"
end

I tried this and it seems to work but I wonder if there's a better way (recursion)?我试过这个,它似乎工作,但我想知道是否有更好的方法(递归)?

coverage_hash_arr.collect do |the_hash|
    the_hash.each do |key,value|
        key == :Module ? markdown << "--------- Status for #{value} ----------\n" : markdown << " - #{key}: #{value} \n"
      end
      markdown << "------------------------------------\n\n"
end

You could:你可以:

  • use puts instead of << to avoid explicit newlines使用puts而不是<<来避免显式换行
  • usecenter to center the caption horizontally使用center将标题水平居中
  • use map to generate the attribute strings and utilize puts ' behavior of printing array elements on separate lines使用map生成属性字符串并利用puts ' 在单独的行上打印数组元素的行为
  • use without to get a hash without the :Module key使用without获得没有:Module密钥的 hash
  • use * to repeat a string使用*重复一个字符串

Applied to your code:应用于您的代码:

markdown = StringIO.new

coverage_hash_arr.each do |hash|
  markdown.puts " Status on #{hash[:Module]} ".center(46, '-')
  markdown.puts hash.without(:Module).map { |k, v| "- #{k}: #{v}" }
  markdown.puts '-' * 46
  markdown.puts
end

Output via puts markdown.string : Output 通过puts markdown.string

-------------- Status on Mobile --------------
- name: Sheila Chapman
- age: 21
----------------------------------------------

--------------- Status on Web ----------------
- name: Hendricks Walton
- age: 40
----------------------------------------------

--------------- Status on Misc ---------------
- name: Torres Mcdonald
- age: 39
----------------------------------------------

Note that the above isn't proper Markdown syntax.请注意,以上不是正确的 Markdown 语法。 You might want to change your output to something like this:您可能希望将 output 更改为以下内容:

### Status on Mobile
- name: Sheila Chapman
- age: 21

### Status on Web
- name: Hendricks Walton
- age: 40

### Status on Misc
- name: Torres Mcdonald
- age: 39

Here's a more streamlined version which has been adapted to be more idiomatic Ruby:这是一个更精简的版本,它已被改编为更惯用的 Ruby:

# Define your hashes with keys having consistent case, and omit extraneous
# surrounding quotes unless defining keys like "this-name" which are not
# valid without escaping.
coverage = [
  {
    module: "Mobile",
    name: "Sheila Chapman",
    age: 21
  },
  {
    module: "Web",
    name: "Hendricks Walton",
    age: 40
  },
  {
    module: "Misc",
    name: "Torres Mcdonald",
    age: 39
  }
]

# Iterate over each of these elements...
coverage.each do |entry|
  markdown << "------- Status on #{entry[:module]} -------\n"

  entry.each do |key, value|
    # Skip a particular key
    next if (key == :module)

    markdown << "- #{key}: #{value} \n"
  end

  markdown << "----------------------------------------------\n"
end

This can be adapted to have a list of keys to exclude, or the inverse, of having a list of keys to actually print.这可以调整为具有要排除的键列表,或者相反,具有要实际打印的键列表。

There's really nothing wrong with your approach specifically.你的方法确实没有什么问题。 The major faux-pas committed is in using delete on the data, which mangles it, rendering it useless if you needed to print this again.主要的失误是在数据上使用delete ,这会破坏它,如果你需要再次打印它,它就会变得无用。

It's generally best to try and avoid tampering with the data you're iterating over unless the purpose of that code is clear in its intent to alter it.通常最好尽量避免篡改您正在迭代的数据,除非该代码的目的是明确的改变它的意图。

It looks like your input data has always the same key/value pairs and I would be more explicit to make it easier to read and to understand what the actual output is:看起来您的输入数据始终具有相同的键/值对,我会更明确地使其更易于阅读并理解实际的 output 是什么:

coverage_hash_arr.each do |hash|
  markdown << <<~STRING
    ------- Status on #{hash[:Module]} -------
    - name: #{hash[:name]}
    - age:  #{hash[:age]}
    ----------------------------------------------
  STRING
end

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

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