如何解决如何在 ruby 的散列中制作 deep_slice
我一直在寻找一种干净的方法来做到这一点,我找到了一些解决方法,但没有找到像切片这样的东西(有些人建议使用 gem,但我认为此操作不需要,如果我我错了),所以我发现自己有一个包含一堆散列的散列,我想要一种方法来对这个散列执行 Slice 操作,并从嵌套散列中获取键/值对,所以问题是:
ruby 中是否有类似 deep_slice 的东西?
示例:
input: a = {b: 45,c: {d: 55,e: { f: 12}},g: {z: 90}},keys = [:b,:f,:z]
expected output: {:b=>45,:f=>12,:z=>90}
提前谢谢! ?
解决方法
环顾四周后,我决定自己实现它,这就是我解决它的方法:
a = {b: 45,c: {d: 55,e: { f: 12}},g: {z: 90}}
keys = [:b,:f,:z]
def custom_deep_slice(a:,keys:)
result = a.slice(*keys)
a.keys.each do |k|
if a[k].class == Hash
result.merge! custom_deep_slice(a: a[k],keys: keys)
end
end
result
end
c_deep_slice = custom_deep_slice(a: a,keys: keys)
p c_deep_slice
上面的代码是一个经典的DFS,它利用了哈希类提供的merge!。
您可以测试上面的代码here
,require 'set'
def recurse(h,keys)
h.each_with_object([]) do |(k,v),arr|
if keys.include?(k)
arr << [k,v]
elsif v.is_a?(Hash)
arr.concat(recurse(v,keys))
end
end
end
hash = { b: 45,c: { d: 55,e: { f: 12 } },g: { b: 21,z: 90 } }
keys = [:b,:z]
arr = recurse(hash,keys.to_set)
#=> [[:b,45],[:f,12],[:b,21],[:z,90]]
请注意,hash
与问题中给出的示例哈希略有不同。我添加了第二个嵌套键 :b
来说明返回散列而不是键值对数组的问题。如果我们将 arr
转换为散列,则 [:b,45]
对将被丢弃:
arr.to_h
#=> {:b=>21,:f=>12,:z=>90}
但是,如果需要,可以写:
arr.each_with_object({}) { |(k,h| (h[k] ||= []) << v }
#=> {:b=>[45,:f=>[12],:z=>[90]}
我将 keys
从数组转换为集合只是为了加快查找速度 (keys.include?(k)
)。
如果散列包含嵌套散列数组和嵌套散列,则可以使用稍微修改的方法。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。