下面,我们将获得一个名为win_lose的数组。我们应该创建一个看起来像下面的哈希的哈希。我最初的倾向是使用.count做一些事情,但在尝试答案之后,.each_with_object工作得最好。
有人可以根据.each_with_object方法正在做什么和答案本身来打破它吗?我得到了答案,并从阅读文档中找到了答案,但仍然需要解释方法本身......
谢谢!
win_lose = ["win", "lose", "win", "lose", "win", "win"]
基于win_lose数组创建一个如下所示的哈希:
win_loss_count = {
"win" => 4,
"loss" => 2
}
这是我最初尝试的没有成功:
win_loss_count = Hash[win_lose.map.with_index { |outcome, times| outcome = times.count }]
答案:
win_loss_count = win_lose.each_with_object(Hash.new(0)) { |word,counts| counts[word] += 1 }
答案 0 :(得分:5)
each_with_object
非常简洁。它就像each
,但每次都有一个额外的对象。
所以对此:
win_lose.each_with_object(Hash.new(0)) { |word,counts| counts[word] += 1 }
您每次都在调用each
,同时传入通过Hash.new(0)
创建的对象。 word
是您在普通each
中得到的词,counts
是被称为“with_object”的“对象”(因此,哈希)。
此快捷方式的重点是Hash.new(0)
。这意味着创建一个新的空哈希值,其中0表示以前不存在的所有键的值,即使之前不存在counts[word] += 1
,也可以使用each_with_object
。
最后,counts
返回“对象”,因此会返回{{1}},并为每个单词进行修改。
答案 1 :(得分:2)
Nick完全正确,实际上有其他方法可以将对象传递到块中以帮助您,但是您的结构需要输出。您将在ruby中看到的最常见的一种是Enumerable#inject
方法。您可以像
win_lose.inject(Hash.new(0)) { |hash, val| hash[val] += 1; hash }
执行相同的操作:
[14] pry(main)> win_lose
=> ["win", "lose", "win", "lose", "win", "win"]
[15] pry(main)> win_lose.inject(Hash.new(0)) { |hash, val| hash[val] += 1; hash }
=> {"win"=>4, "lose"=>2}
我们正在做同样的事情,我们发送的哈希值默认值为零,我们正在构建每次迭代的新哈希。