首页 > 解决方案 > 迭代嵌套哈希以获取字符串数组

问题描述

我有一个这样的嵌套哈希:

s = Struct.new :topic_version

s_blank = s.new
s_bar = s.new "bar"
s_foo = s.new "foo"

h = {
  :aa=>{:services=>[nil, s_blank, s_bar]},
  :ab=>{:services=>[s_blank, nil, s_bar, s_bar]},
  :ac=>{:services=>[nil, s_foo, s_blank]}
} 

我想得到一个字符串值数组,例如。["bar", baz"]

我的尝试是:

@topic_version_collection = []
h.each do |key, value| 
  value[:services].each do |v|
    @topic_version_collection << v.topic_version
  end
end

如果nil数组中没有任何值,它就可以工作。

但是我怎样才能让它与 nils 一起工作呢?

标签: ruby

解决方案


这里懒惰的方式是使用条件导航操作符,或者换句话说:

v&.topic_version

nilif vis返回的位置nil

不过,这只是表面问题。当你看到模式时:

x = [ ]
y.each do |z|
  x << z.a
end

你真正想要的是:

x = y.map(&:a)

Where有助于使用 1:1映射将map一个数组中的值转换为另一个数组中的值。

要在这里建立一个解决方案,首先values从哈希中去除 ,然后在嵌套的哈希中提取:services键,然后调用topic_version所有非nil条目。由于那些可以返回nil,最后去掉nilcompact

换句话说:

h.values.map do |v|
  v[:services]
end.flat_map do |v|
  v.compact.map(&:topic_version)
end.compact

现在,如果您希望它们独一无二,请.uniq在最后添加。

flat_map是一种将多个结果数组组合成单个最终结果的方法。


推荐阅读