Reputation: 810
I have the following Array (no limit of deepness) :
[
{
name: "foo",
age: 12,
children: [{
name: "zoo",
age: 44
},
{
name: "taz",
age: 17,
children: [{
name: 'tof',
age: 23
},
{
name: 'tok',
age: 42
}
]
}
]
},
{
name: "bar",
age: 54
}
]
And I would like to collect all the different values of the key name
, in this example the result would be:
(the order does not matter)
['foo', 'zoo', 'taz', 'tof', 'tok', 'bar']
with a function like
def func(my_array, "name")
Do you have any idea how I should code that function ?
Upvotes: 1
Views: 199
Reputation: 110675
def find_em(arr)
arr.each_with_object([]) do |h,a|
a << h[:name]
a.concat(find_em(h[:children])) if h.key?(:children)
end
end
find_em(arr)
#=> ["foo", "zoo", "taz", "tof", "tok", "bar"]
Upvotes: 0
Reputation: 796
Heres a fast but brittle regex way of doing it
def find_nested(arr, key)
arr.to_s.scan(/#{key.to_sym}=>"([^"]+)/).flatten
end
Upvotes: 2
Reputation: 36101
Assuming you know the substructure is under :children
:
def extract(sequence, key)
sequence.flat_map do |hash|
[hash[key], *extract(hash[:children] || [], key)]
end
end
Upvotes: 4
Reputation: 211560
Here's a way of doing it using case
to differentiate between the various object types you'll encounter:
def find_names(object, key_name)
case (object)
when Array
object.flat_map do |e|
find_names(e, key_name)
end
when Hash
[ object[key_name] ] + find_names(object.values, key_name).compact
end
end
Upvotes: 2