Suppose I have an Array
like this
data = [
{
key: val,
important_key_1: { # call this the big hash
key: val,
important_key_2: [
{ # call this the small hash
key: val,
},
{
key: val,
},
]
},
},
{
key: val,
important_key_1: {
key: val,
important_key_2: [
{
key: val,
},
{
key: val,
},
]
},
},
]
I want to create a lazy enumerator that would return the next small hash on each #next
, and move on to the next big hash and do the same when the first big hash reaches the end
The easy way to return all the internal hashes that I want would be something like this
data[:important_key_1].map do |internal_data|
internal_data[:important_key_2]
end.flatten
Is there someway to do this or do I need to implement my own logic ?
This returns a lazy enumerator which iterates over all the small hashes :
def lazy_nested_hashes(data)
enum = Enumerator.new do |yielder|
data.each do |internal_data|
internal_data[:important_key_1][:important_key_2].each do |small_hash|
yielder << small_hash
end
end
end
enum.lazy
end
With your input data and a val
definition :
@i = 0
def val
@i += 1
end
It outputs :
puts lazy_nested_hashes(data).to_a.inspect
#=> [{:key=>3}, {:key=>4}, {:key=>7}, {:key=>8}]
puts lazy_nested_hashes(data).map { |x| x[:key] }.find { |k| k > 3 }
#=> 4
For the second example, the second big hash isn't considered at all (thanks to enum.lazy
)