arrays - Ruby:我怎样才能把这个数组转换成这个哈希?
问题描述
我有一个数组数组。数组中的每个项目都包含三个字符串:腿数、动物和声音。
a = [ ['4', 'dog', 'woof'] , ['4', 'cow', 'moo'], ['2', 'human', 'yo'] , ['2', 'yeti', 'wrarghh'] ]
我想把数组变成这个哈希:
{
'2' => [ { 'human' => 'yo' }, { 'yeti' => 'wrarghh'} ],
'4' => [ { 'dog' => 'woof' }, { 'cow' => 'moo'} ]
}
我认为减少将是要走的路,但我运气不好。我目前的刺伤看起来像:
a.reduce({}) do |acc, item|
acc[item.first] = [] unless acc.key? item.first
acc[item.first] << { item[1] => item[2] }
end
但它得到一个错误:
NoMethodError: undefined method `key?' for [{"dog"=>"woof"}]:Array
实现这一目标的最佳方法是什么?
解决方案
a.each_with_object({}) { |(kout, kin, val), h| (h[kout] ||= []) << { kin => val } }
#=> {"4"=>[{"dog"=>"woof"}, {"cow"=>"moo"}], "2"=>[{"man"=>"yo"}, {"yeti"=>"wrarghh"}]}
我们有
enum = a.each_with_object({})
#=> #<Enumerator: [["4", "dog", "woof"], ["4", "cow", "moo"], ["2", "man", "yo"],
# ["2", "yeti", "wrarghh"]]:each_with_object({})>
第一个值由此枚举器生成并传递给块,并为块变量赋值:
(kout, kin, val), h = enum.next
#=> [["4", "dog", "woof"], {}]
分解如下。
kout
#=> "4"
kin
#=> "dog"
val
#=> "woof"
h #=> {}
因此,块计算是
(h[kout] ||= []) << { kin => val }
#=> (h[kout] = h[kout] || []) << { "dog" => "wolf" }
#=> (h["4"] = h["4"] || []) << { "dog" => "wolf" }
#=> (h["4"] = nil ||= []) << { "dog" => "wolf" }
#=> (h["4"] = []) << { "dog" => "wolf" }
#=> [] << { "dog" => "wolf" }
#=> [{ "dog" => "wolf" }]
h["4"] || [] #=> []
因为h
没有密钥"4"
,因此h["4"] #=> nil
。
的下一个值enum
被传递给块并重复计算。
(kout, kin, val), h = enum.next
#=> [["4", "cow", "moo"], {"4"=>[{"dog"=>"woof"}]}]
kout
#=> "4"
kin
#=> "cow"
val
#=> "moo"
h #=> {"4"=>[{"dog"=>"woof"}]}
(h[kout] ||= []) << { kin => val }
#=> (h[kout] = h[kout] || []) << { "cow" => "moo" }
#=> (h["4"] = h["4"] || []) << { "cow" => "moo" }
#=> (h["4"] = [{"dog"=>"woof"}] ||= []) << { "cow" => "moo" }
#=> (h["4"] = [{"dog"=>"woof"}]) << { "cow" => "moo" }
#=> [{"dog"=>"woof"}] << { "cow" => "moo" }
#=> [{ "dog" => "wolf" }, { "cow" => "moo" }]
这一次h["4"] || [] #=> [{ "dog" => "wolf" }]
是因为h
现在有一个"4"
具有真值 ( [{ "dog" => "wolf" }]
) 的键。
其余计算类似。
推荐阅读
- r - 如果特定列中的值在分组类别中不同,则删除数据框的行
- azure-data-factory-2 - Azure 数据工厂 V2 中的 Oracle 存储过程
- java - Firebase 首先连接到应用程序,然后出现 Internet 错误并且无法第二次连接
- bash - 向 Docker 发送 2 个命令,其中 1 个是输出到另一个
- mysql - MySQL 查找和替换 - 添加换行符
- ios - 经典蓝牙实现iOS
- go - 将protobuf消息转换为结构后添加了一些奇怪的字段?
- php - 用if子句匹配字符串而不检查php中的大写
- sql - 子查询中的动态表名和变量
- python-3.x - Python Asyncio - 服务器能够在不同时间接收多命令并处理它