I'm getting strange behavior when trying to select
from a hash created with group_by
:
尝试从使用group_by创建的哈希中进行选择时,我会遇到奇怪的行为:
When I run
当我跑
all_records.group_by(&:opportunity).map{|foo| foo[1].length != 1 }.select{|x| x}
I get some elements back: => [true, true]
我得到了一些元素:=> [true,true]
Yet when I try and select, with the exact block I map
ped:
然而,当我尝试选择时,使用我映射的确切块:
all_records.group_by(&:opportunity).select{|foo| foo[1].length != 1 }
I get no results: => {}
我没有得到任何结果:=> {}
Just as a sanity check, it works as expected when i first convert the hash to an array with sort
:
正如一个完整性检查,当我第一次将哈希转换为具有排序的数组时,它按预期工作:
all_records.group_by(&:opportunity).sort.select{|foo| foo[1].length != 1 }.length
Result: => 2
结果:=> 2
It's strange to me, because the first result indicates that the hash recognized the foo[1]
command perfectly. What's causing this?
这对我来说很奇怪,因为第一个结果表明哈希完全识别了foo [1]命令。是什么导致了这个?
1 个解决方案
#1
2
In the first snippet you are doing a Enumerable#map
on a hash, with a block that gets a single argument (why don't you unpack it?), and here you get a pair (as you expected). In the second snippet you are doing a Hash#select
again with a single argument (and again you should unpack the key/value), but here you get only the key, not the pair (because of how the method is implemented, check the source code for details).
在第一个片段中,你在一个哈希上做一个Enumerable #map,一个块得到一个参数(为什么你不解压缩?),在这里你得到一对(如你所料)。在第二个片段中,您正在使用单个参数再次执行Hash #select(并且您应该再次解压缩键/值),但是这里只获取键,而不是对(因为方法的实现方式,请检查源代码详情)。
>> {a: 1, b: 2}.map { |x| p x }
[:a, 1]
[:b, 2]
>> {a: 1, b: 2}.select { |x| p x }
:a
:b
If you go to the docs for Hash#select, you'll see it explicitly requires unpacked arguments. Conclusion: always unpack the key/value when iterating hashes with any method:
如果你转到Hash #select的文档,你会发现它显然需要解压缩的参数。结论:在使用任何方法迭代哈希时,始终解压缩键/值:
records.group_by(&:opportunity).select { |key, values| values.length > 1 }
#1
2
In the first snippet you are doing a Enumerable#map
on a hash, with a block that gets a single argument (why don't you unpack it?), and here you get a pair (as you expected). In the second snippet you are doing a Hash#select
again with a single argument (and again you should unpack the key/value), but here you get only the key, not the pair (because of how the method is implemented, check the source code for details).
在第一个片段中,你在一个哈希上做一个Enumerable #map,一个块得到一个参数(为什么你不解压缩?),在这里你得到一对(如你所料)。在第二个片段中,您正在使用单个参数再次执行Hash #select(并且您应该再次解压缩键/值),但是这里只获取键,而不是对(因为方法的实现方式,请检查源代码详情)。
>> {a: 1, b: 2}.map { |x| p x }
[:a, 1]
[:b, 2]
>> {a: 1, b: 2}.select { |x| p x }
:a
:b
If you go to the docs for Hash#select, you'll see it explicitly requires unpacked arguments. Conclusion: always unpack the key/value when iterating hashes with any method:
如果你转到Hash #select的文档,你会发现它显然需要解压缩的参数。结论:在使用任何方法迭代哈希时,始终解压缩键/值:
records.group_by(&:opportunity).select { |key, values| values.length > 1 }