Ruby 如果 none 存在,如何迭代集合并创建哈希键,或者如果键存在,则添加到值

Ruby how to iterate a collection and create a hash key if none exists, or add to the value if key does exist

这是我发现自己经常使用的模式,我想知道内置库中是否有某些东西可以在不添加所有这些控制流语句的情况下执行此操作。我所拥有的是:

input = <<TEXT
/us/programming/sports:model.channel.tnt.name
/us/programming/sports:model.channel.spice.name
/us/programming/sports:model.classificationwebgenre.us-entertainment.programming_link_text
/international-sports/package:model.language.international-sports.name
/brazilian/programming/sports:model.package.hbo-extra.description
TEXT


def self.create_hash(text)
  output = {}
  text.each_line("\n") do |line|
    split_lines = line.split(":")
    if output.has_key?(split_lines.first)
      output[split_lines.first] << split_lines[1][0..-2]
    else
      output[split_lines.first] = [split_lines[1][0..-2]]
    end
  end
  output
end

结束

这个输出也是:

{
      "/us/programming/sports" => ["model.channel.tnt.name", "model.channel.spice.name", "model.classificationwebgenre.us-entertainment.programming_link_text"],
      "/international-sports/package" => ["model.language.international-sports.name"],
      "/brazilian/programming/sports" => ["model.package.hbo-extra.description"]
    }

我写这篇文章的方式是否只是让事情变得过于复杂?在 ruby 中是否有惯用的写法?提前致谢。

只需使用默认值定义 output

output = Hash.new { |k, v| k[v] = [] }

这会将您的代码变成:

def self.create_hash(text)
  output = Hash.new { |k, v| k[v] = [] }
  text.each_line("\n") do |line|
    split_lines = line.split(":")
    output[split_lines.first] << split_lines[1][0..-2]
  end
  output
end

不确定是否更快,但更干净

def self.create_hash(text)
  output = {}
  text.each_line("\n") do |line|
    split_lines = line.split(":")
    output[split_lines.first] ||= []
    output[split_lines.first] << split_lines[1][0..-2]
  end
  output
end