Array of hashes newbie question

Hi all!

I hope this is the right place to ask my question.

I’m trying to get information about my droplets on DigitalOcean.
Information comes as array of hashes:

[{“id”=>1,
“name”=>“MyTestDroplet”,
“image_id”=>6918990,
“size_id”=>66,
“region_id”=>9,
“backups_active”=>false,
“ip_address”=>“1.1.1.1”,
“private_ip_address”=>nil,
“locked”=>false,
“status”=>“off”,
“created_at”=>“2014-12-08T15:40:09Z”},
{“id”=>2,
“name”=>“MyTestDroplet2”,
“image_id”=>6918990,
“size_id”=>66,
“region_id”=>7,
“backups_active”=>false,
“ip_address”=>“2.2.2.2”,
“private_ip_address”=>nil,
“locked”=>false,
“status”=>“off”,
“created_at”=>“2014-12-09T19:27:34Z”}]

My question is how can I get values of specific keys of both hashes?
I need to get information like this:

1
MyTestDroplet
1.1.1.1

2
MyTestDroplet2
2.2.2.2

And number of hashes can be any (as well as number of droplets on
DigitalOcean).

Thank you in advance!

On Dec 9, 2014, at 15:00, Paul L. [email protected] wrote:

"size_id"=>66,

“size_id”=>66,
I need to get information like this:

1
MyTestDroplet
1.1.1.1

2
MyTestDroplet2
2.2.2.2

hash.map{|h| h[‘name’]}

Assuming you place the array in a variable called droplets

droplets.each { |droplet|
puts droplet[‘id’]
puts droplet[‘name’]
puts droplet[‘ip_address’]
}

John

Thank you! It works!

2014-12-09 23:02 GMT+03:00 Bryce K. [email protected]:

It works only with arrays, as I understand.
With array of hashes I get an error:

no implicit conversion of String into Integer (TypeError)

2014-12-09 23:04 GMT+03:00 John W Higgins [email protected]:

On 2014-Dec-9, at 15:10 , Paul L. [email protected] wrote:

puts droplet[‘name’]
puts droplet[‘ip_address’]
}

John

С уважением,
Павел “Che” Лецкий

irb2.1.5> droplets.map {|h| h.values_at(‘id’, ‘name’, ‘ip_address’)}
#2.1.5 => [[1, “MyTestDroplet”, “1.1.1.1”], [2, “MyTestDroplet2”,
“2.2.2.2”]]

You can learn more about Array#map (actually Enumerable#map) and
Hash#values_at from the documentation:

From APIdock.com
map (Array) - APIdock
values_at (Hash) - APIdock

or from Ruby-Lang.org
Class: Array (Ruby 2.1.5)
Class: Hash (Ruby 2.1.5)

-Rob

Hi,

On 9 Dec 2014, at 22:10, Paul L. [email protected] wrote:

It works only with arrays, as I understand.

You can iterate through Arrays or Hashes depends on the situation. In
your case you have an ‘Array’ of ‘Hashes’. A very common pattern in
ruby. So first you need to iterate through the Array, then you can work
with each entry of the array, which is your case is a Hash object. Here
is another code sample (simpler tho read IMHO the the other ones):

#!/usr/bin/env ruby

droplets = [{“id”=>1,
“name”=>“MyTestDroplet”,
“image_id”=>6918990,
“size_id”=>66,
“region_id”=>9,
“backups_active”=>false,
“ip_address”=>“1.1.1.1”,
“private_ip_address”=>nil,
“locked”=>false,
“status”=>“off”,
“created_at”=>“2014-12-08T15:40:09Z”},
{“id”=>2,
“name”=>“MyTestDroplet2”,
“image_id”=>6918990,
“size_id”=>66,
“region_id”=>7,
“backups_active”=>false,
“ip_address”=>“2.2.2.2”,
“private_ip_address”=>nil,
“locked”=>false,
“status”=>“off”,
“created_at”=>“2014-12-09T19:27:34Z”}]

p droplets.class # => Array

p droplets[0].class # => Hash

counter = 1

Iterate through Array entries here

droplets.each do |entry|

Now ‘entry’ is a hash.

We access hash values by requesting ‘keys’

puts “”
puts “Entry: #{counter}”
puts entry[“name”] # => MyTestDroplet …
puts entry[“image_id”] # => 6918990
puts “-”*3
counter += 1
end

With array of hashes I get an error:

no implicit conversion of String into Integer (TypeError)

What kind of code gives you this error? Can you show us your snippet?

best regards

Panagiotis (atmosx) Atmatzidis

email: [email protected]
URL: http://www.convalesco.org
GnuPG ID: 0x1A7BFEC5
gpg --keyserver pgp.mit.edu --recv-keys 1A7BFEC5

“As you set out for Ithaca, hope the voyage is a long one, full of
adventure, full of discovery […]” - C. P. Cavafy

On 2014-Dec-9, at 16:01 , Panagiotis A. [email protected]
wrote:

droplets = [{“id”=>1,
{“id”=>2,

puts “Entry: #{counter}”
puts entry[“name”] # => MyTestDroplet …
puts entry[“image_id”] # => 6918990
puts “-”*3
counter += 1
end

Just a note about the use of a separate counter variable.

irb2.1.5> array = %w[ a b c d e ]
#2.1.5 => [“a”, “b”, “c”, “d”, “e”]

Array#each gives you one element at a time:

irb2.1.5> array.each {|element| puts “#{element}” }; nil
a
b
c
d
e

If you need the array index of the element, you can use the #with_index
method:

irb2.1.5> array.each.with_index {|element, index| puts “#{index}:
#{element}” }; nil
0: a
1: b
2: c
3: d
4: e

Which is 0-based by default, but you can also provide an initial value:

irb2.1.5> array.each.with_index(1) {|element, index| puts “#{index}:
#{element}” }; nil
1: a
2: b
3: c
4: d
5: e

which is exactly your counter.

droplets.each.with_index(1) do |entry, counter|

puts various things

end

-Rob

        "ip_address"=>"1.1.1.1",
         "ip_address"=>"2.2.2.2",

Iterate through Array entries here

c
4: e
which is exactly your counter.

droplets.each.with_index(1) do |entry, counter|

puts various things

end

-Rob

Oh, thanks for the pointer Rob. Using with_index like that never
occurred to me. Admittedly it looks much cleaner!

Panagiotis (atmosx) Atmatzidis

email: [email protected]
URL: http://www.convalesco.org
GnuPG ID: 0x1A7BFEC5
gpg --keyserver pgp.mit.edu --recv-keys 1A7BFEC5

“As you set out for Ithaca, hope the voyage is a long one, full of
adventure, full of discovery […]” - C. P. Cavafy