I am working on an Rails API that receives POSTed json input and processes things accordingly. The current element involves prizes and prize codes, and I have a question about hashes, arrays, and the ruby .first
method.
Disclaimer: I am receiving json from a legacy PHP application and as of right now I don't have a way to edit the output from that application. I'm getting it as is and am dealing with it the best I can.
The prize codes are coming in as a nested element within a larger object, but we are just going to focus on the codes for now. Here's what I'm getting:
"codes" => {
"0"=>{"Code"=>"1582566"},
"1"=>{"Code"=>"2153094"},
"2"=>{"Code"=>"3968052"},
"3"=>{"Code"=>"4702730"},
"4"=>{"Code"=>"5582567"},
"5"=>{"Code"=>"6153097"},
"6"=>{"Code"=>"7968052"},
"7"=>{"Code"=>"8702730"},
"8"=>{"Code"=>"9582567"},
"9"=>{"Code"=>"1053097"}
}
Starting there, everything gets pulled into a block, and then I am dealing with each code individually.
I'm going to start with my final solution and we will work our way backwards. In order to get a single code, just the number, out of each code, this is my solution:
code[1].first.second.to_i
returns 1582566
Now let's rewind, and start at the beginning.
code
returns "0"=>{"Code"=>"1582566"}
That makes sense. Now I want to skip past that first level "0"
.
code[1]
returns {"Code"=>"1582566"}
All of that makes sense so far, but this is where things get weird. From that point I want to grab the 2nd item, maybe you might call it the value in this hashy key value pair. Unfortunately, the ruby .second
doesn't work on a hash, I get an undefined method
error, but .first
does for some reason. And the output is confusing to me.
code[1].first
returns ["Code", "4582566"]
And now all of a sudden that hash is an array. Why does the ruby .first
array method turn a key value hash into an array?
I did a little sleuthing and discovered that :first
is a method listed in the output from code[1].methods
, but I can't seem to find any documentation out there about what it does.
code[1].class
returns Hash
But then why do I get a completely different set of available methods returned when I run code[1].methods
vs Hash.methods
? The :first
method is listed in the output from code[1].methods
but NOT in the output from Hash.methods
and it is not on the list of available methods here either:
http://ruby-doc.org/core-2.1.5/Hash.html
If they are both Hashes, why are their different methods available? Does it have something to do with class methods vs instance methods?
I'm still confused about what exactly the .first
method does to a hash.
In the end I realized a better / cleaner way to get what is code[1]['Code'].to_i
, but I'm still curious about what is going on under the hood.
In Ruby, a Hash
is an ordered collection of key/value pairs . We can say they are "ordered" because:
Hashes enumerate their values in the order that the corresponding keys were inserted.
Because of this ordered enumeration, the Enumberable#first
method returns the first key/value pair that was added to the hash as an Array of two items [key, value]
.
{}.first # => nil
{1 => 2}.first # => [1, 2]
{:a => true, :b => false}.first # => [:a, true]
h = Hash.new
h[:m] = "n"
h[:o] = "p"
h.first # => [:m, "n"]
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.