I have an array of hashes which also include an array:
machines = [{ 'name' => 'ldapserver1', 'ip' => '10.199.0.10',
'role' => ['server', 'initial'] },
{ 'name' => 'ldapserver2', 'ip' => '10.199.0.11',
'role' => ['server', 'secondary'] },
{ 'name' => 'ldapclient1', 'ip' => '10.199.0.12',
'role' => 'client' },
{ 'name' => 'ldapclient2', 'ip' => '10.199.0.13',
'role' => 'client' }]
I want to search thru it to get the machine with a matching role.
I can use this to get machines with the client role:
results = @machines.select { |machine| machine['role'] == 'client' }
[{"name"=>"ldapclient1", "ip"=>"10.199.0.12", "role"=>"client"}, {"name"=>"ldapclient2", "ip"=>"10.199.0.13", "role"=>"client"}]
But when I try to search the array of roles this breaks:
results = machines.select { |machine| machine['role'] == 'server' }
[]
How can I search through the role arrays to find matches for my machines?
This is a perfect use-case for Enumerable#grep
:
machines.reject { |m| [*m['role']].grep('server').empty? }
Here a splat is used to produce an array from both Array
instance and the String
instance.
As per your code the roles can be string or array so safe to check using following
results = machines.select { |machine| Array(machine['role']).include?('server') }
Update: using Array, this method tries to create array by calling to_ary, then to_a on its argument.
That is because 'role'
can be a string or an array.
Using #include?
will match part of a string if it's a string. Or fully match a string inside an array.
Try:
results = machines.select { |machine| machine['role'].include?('server') }
Or more robust
results = machines.select do |machine|
r = machine['role']
if r.is_a? String
r == 'server'
else
r.include?('server')
end
end
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.