1

I have a nested hash like this:

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]}
} 

And I'd like to get an array of string values eg. ["bar", baz"]

My attempt is:

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

And it works if there aren't any nil values in the array.

But how can I make it work with nils?

2
  • 1
    Where does "baz" come from? Can you add an if !v.nil? check? Commented Aug 27, 2019 at 16:29
  • 1
    Note it is more idiomatic to capitalize classes: S = Struct.new :topic_version Commented Aug 27, 2019 at 19:15

1 Answer 1

1

The lazy way here is to use the conditional navigation operator, or in other words:

v&.topic_version

Where that returns nil if v is nil.

That's just scratching the surface, though. When you see the pattern:

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

What you really want is:

x = y.map(&:a)

Where map helps transform values in one array to values in another using a 1:1 mapping.

To build up to a solution here first strip out the values from the Hash, then pull the :services key in that nested Hash, then call topic_version on all non-nil entries. Since those can return nil, strip out nil with compact at the end.

In other words:

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

Now if you want them unique, add .uniq at the end.

The flat_map here is a way of combining multiple result arrays into a singular final result.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.