【问题标题】:Inject with multiple block parameters注入多个块参数
【发布时间】:2011-10-19 18:32:45
【问题描述】:

Solr 的 Sunspot gem 有一个方法需要一个包含 2 个元素的块:

search.each_hit_with_result do |hit,result|

我正在使用它来构建一个新的结果哈希,如下所示:

results = Hash.new

search.each_hit_with_result do |hit,result|
  results[result.category.title] = hit.score
end

这很酷,但我不禁想到有一种更“红宝石”的方式来做这件事,我一直在研究很棒的 inject 方法。我认为应该可以进行以下操作,但我无法让它在语法上起作用。有人有什么想法吗?

search.each_hit_with_result.inject({})
{|newhash,|hit,result||newhash[result.category.title]=hit.score}

【问题讨论】:

  • 将搜索映射到一个标题数组并为 2 个元素数组评分,然后在该数组数组上使用 Hash[foo]。今天晚些时候我会写这个作为正确的答案。
  • 没关系,tokland 打败了我!

标签: ruby


【解决方案1】:

我相信该方法看起来像您想要的:

search.each_hit_with_result.inject({}) { |new_hash, current| new_hash[current[0]] = current[1]; new_hash }

希望对你有所帮助。

【讨论】:

  • 是的。没有 SOLR 的快速测试: Hash.inject 似乎与 each* 方法的行为相同,因为它传递了 2 个参数。所以:{1=>2, 3=>4}.inject({}) { |new_hash, current|新哈希[当前[0]] = 当前[1];新哈希}
  • 您可以使用 each_with_object 代替注入。
【解决方案2】:

Object#enum_for 正是为此而设计的:

hit_results = search.enum_for(:each_hit_with_result)
results = Hash[hit_results.map { |hit, res| [res.category.title, hit.score] }]

在我看来,代码永远不应该暴露each_xyz 方法,它们会推广臭气熏天的命令式代码(正如您正确检测到的那样)。这种方法在没有enumerators的情况下是可以理解的,你需要延迟返回数据,但现在它应该被认为是一种反模式。他们应该返回一个可枚举或枚举器,并让用户决定如何使用它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多