Extracting only specific members from a Ruby hash - ruby-on-rails

I would like to extract only the team_member_id and display_name from the below hash returned from dropbox api.
{"members"=>[{"profile"=>{"team_member_id"=>"dbmid:AACHnGyTHHna44224Ad-vVewFDJ9nzS7be9GJ6Tc", "account_id"=>"dbid:AAD234234234x2yGXHsG3guC04Fp8QPwUF9NDO55w", "email"=>"name#domain.com", "email_verified"=>true, "secondary_emails"=>[], "status"=>{".tag"=>"active"}, "name"=>{"given_name"=>"firstname", "surname"=>"lastname", "familiar_name"=>"first", "display_name"=>"firstname lastname", "abbreviated_name"=>"MM"}, "membership_type"=>{".tag"=>"full"}, "joined_on"=>"2017-01-02T20:58:20Z", "groups"=>["g:6fe6b5a111cfc0400000000000000005", "g:6fe6b5a111cfc04000000000000015a1", "g:6fe6b5a111cfc0400000000000002299", "g:6fe6b5a111cfc04000000000000043cb", "g:6fe6b5a111cfc0400000000000056eb3", "g:6fe6b5a111cfc0400000000000058122", "g:6fe6b5a111cfc0400000000000058248", "g:6fe6b5a111cfc04000000000002dd0d9", "g:6fe6b5a111cfc04000000000002dd650"], "member_folder_id"=>"1384307556"}, "role"=>{".tag"=>"team_admin"}}], "cursor"=>"AAAXuLKhvS_T97ZjALBH4A2MCQW_xOp9bu0tAwqGuY1zBg_C-UKVZoBDTQkhU4Hok8nGT15IHN64ZE-88-dlT3242341WD8RgPBg5zfIOQqAdgJlc-Aw", "has_more"=>true}
I tried using the below code and returned nil.
puts hash['profile']['team_member_id']
What is the recommended way to extract individual data from the above hash.

hash["members"] returns an array, so you would have to do:
hash["members"][0]["profile"]["team_member_id"]
hash["members"][0]["profile"]["name"]["display_name"]
You could also take advantage of the method called dig which works on both hash and array. The advantage with this one is that it returns nil if any key is not found:
hash.dig('members', 0, 'profile', 'team_member_id')
hash.dig('members', 0, 'profile', 'name', 'display_name')

Related

Refer to a hash where the key is an ip_address

I've got a model that I need to group by the :sending_ip, which is a "cidr" column in the database.
#count_hash = Webhook.group('sending_ip').count
Resulting in this hash:
{#<IPAddr: IPv4:213.32.165.239/255.255.255.255>=>127000, #<IPAddr: IPv4:153.92.251.118/255.255.255.255>=>228000}
I cannot figure out how to reference this type of key. Below are some examples of the ways that I've tried to call these keys. All of them return nil or error.
#count_hash[#<IPAddr: IPv4:213.32.165.239/255.255.255.255>]
#count_hash["#<IPAddr: IPv4:213.32.165.239/255.255.255.255>"]
#count_hash[<IPAddr: IPv4:213.32.165.239/255.255.255.255>]
#count_hash["#<IPAddr: IPv4:213.32.165.239/255.255.255.255>"]
Elsewhere in my app, I've got a simpler example that works great. The other example groups by esp, which results in this hash:
{"hotmail"=>1000, "gmail"=>354000}
The second hash, I can refer to easily
#count_hash["gmail"]
To obtain the expected result of 354000
How can I achieve this same functionality with the previous hash that was grouped by sending_ip? Thank you in advance for your insight.
This:
#<IPAddr: IPv4:213.32.165.239/255.255.255.255>
is the result of calling #inspect on an instance of IPAddr. So the keys are IPAddr instances and you can say:
ip = IPAddr.new('213.32.165.239')
#count_hash[ip]
# 127000
Or you could iterate over the hash:
#count_hash.each { |ip, n| ... }
or over its keys:
#count_hash.keys.each { |ip| ... }
depending on what you need to do. You could even convert the keys to strings if that's more convenient:
#count_hash = #count_hash.transform_keys(&:to_s)
# or
#count_hash.transform_keys!(&:to_s)

Generation of table and accessing elements of a Array of Hashes

I have the following Array of hashes in a rails application:
a = ["{\"ROW1\"=>{\"correct\"=>{\"h\"=>\"10\", \"m\"=>\"11\", \"l\"=>
\"12\"}, \"wrong\"=>{\"h\"=>\"2\", \"m\"=>\"2\", \"l\"=>\"4\"}, \"blank
\"=>{\"h\"=>\"2\", \"m\"=>\"4\", \"l\"=>\"3\"}}, \"ROW2\"=>{\"correct
\"=>{\"h\"=>\"2\", \"m\"=>\"4\", \"l\"=>\"4\"}, \"wrong\"=>{\"h
\"=>\"4\", \"m\"=>\"6\", \"l\"=>\"6\"}, \"blank\"=>{\"h\"=>\"7\",
\"m\"=>\"5\", \"l\"=>\"6\"}}, \"ROW3\"=>{\"correct\"=>{\"h\"=>\"4\",
\"m\"=>\"6\", \"l\"=>\"7\"}, \"wrong\"=>{\"h\"=>\"6\", \"m\"=>\"7\",
\"l\"=>\"5\"}, \"blank\"=>{\"h\"=>\"7\", \"m\"=>\"9\", \"l\"=>
\"3\"}}}"]
I want to access its elements and create a database table from it, in the following format
ROW1 correct h=10, m=11,l=12
wrong h=2, m=2,l=4
blank h=2, m=4,l=3
...and similar for ROW2 and ROW3.
How can I do that?
I tried to access a value using
a["ROW1"]["Correct"]["h"]
...but it returns a nil value.
How to access the values of this array of hashes?
you need to first convert the string to hash which can be done as follows:
require 'json'
a = ["{\"ROW1\"=>{\"correct\"=>{\"h\"=>\"10\", \"m\"=>\"11\", \"l\"=>
\"12\"}, \"wrong\"=>{\"h\"=>\"2\", \"m\"=>\"2\", \"l\"=>\"4\"}, \"blank
\"=>{\"h\"=>\"2\", \"m\"=>\"4\", \"l\"=>\"3\"}}, \"ROW2\"=>{\"correct
\"=>{\"h\"=>\"2\", \"m\"=>\"4\", \"l\"=>\"4\"}, \"wrong\"=>{\"h
\"=>\"4\", \"m\"=>\"6\", \"l\"=>\"6\"}, \"blank\"=>{\"h\"=>\"7\",
\"m\"=>\"5\", \"l\"=>\"6\"}}, \"ROW3\"=>{\"correct\"=>{\"h\"=>\"4\",
\"m\"=>\"6\", \"l\"=>\"7\"}, \"wrong\"=>{\"h\"=>\"6\", \"m\"=>\"7\",
\"l\"=>\"5\"}, \"blank\"=>{\"h\"=>\"7\", \"m\"=>\"9\", \"l\"=>
\"3\"}}}"
]
hash_string = a[0]
hash = JSON.parse hash_string.gsub("\n", '').gsub('=>', ':')
# you access the hash now:
hash["ROW1"]["correct"]["h"]
# => 10
Btw, please note that there is a typo. Instead of Correct, the key is correct with small c instead of capital C.
Hope it helps : )

How do I access a hash value that only exists in 1 attribute out of many?

So this one is a bit tricky.
I have an attribute that looks like this:
[22] pry(main)> n.media.meta_info[:response][:outputs]
=> [{"id"=>486,
"url"=>"http://some-video.com/by-fire.mp4",
"label"=>"webmp4",
"state"=>"finished",
"format"=>"mpeg4",
"type"=>"standard",
"frame_rate"=>30.06,
{"id"=>488848287,
"url"=>"http://some-video.com/by-fire.webm",
"label"=>"webwebm",
"state"=>"finished",
"format"=>"webm",
"type"=>"standard",
"frame_rate"=>30.06,
{"id"=>488848288,
"url"=>"http://some-video.com/by-fire.ogv",
"label"=>"webogv",
"state"=>"finished",
"format"=>"ogg",
"type"=>"standard",
"frame_rate"=>30.059,
{"id"=>488848289,
"url"=>
"https://zencoder-temp-storage-us-east-1.s3.amazonaws.com/",
"label"=>nil,
"state"=>"finished",
"format"=>"mpeg4",
"type"=>"standard",
"frame_rate"=>30.06,
"thumbnails"=>
[{"label"=>nil,
"images"=>
[{"dimensions"=>"56x100",
"file_size_bytes"=>15142,
"format"=>"PNG",
"url"=>"https://some-video.s3.amazonaws.com/uploads/video/video_file/id/by-fire.png"}]}],
"md5_checksum"=>nil}]
I am trying to access the thumbnails info, specifically the URL for the thumbnails.
I can't figure out how to get there though.
When I try to go the nested hash key of thumbnails it doesn't work:
[23] pry(main)> n.media.meta_info[:response][:outputs][:thumbnails]
TypeError: no implicit conversion of Symbol into Integer
from (pry):22:in `[]'
Thoughts?
The [{ at the beginning of the output indicates that an array is returned. You first need to find a element in the array that contains a thumbnails key:
outputs = n.media.meta_info[:response][:outputs]
output_with_thumbnail = outputs.find { |elem| elem.keys.include?('thumbnails') }
Then continue like this:
output_with_thumbnail['thumbnails']
If you're just trying to find the thumbnail, and don't care about the rest of the outputs, you can use #find like so:
thumbnails = n.media.meta_info[:response][:outputs].find {|it| it[:thumbnails] }[:thumbnails]
You have an array of hashes, thumbnails are in the 3rd:
n.media.meta_info[:response][:outputs][3][:thumbnails]
It looks like
outputs = n.media.meta_info[:response][:outputs]
is an Array of hashes. So, you need to iterate over them first:
outputs.each do |output|
# deal with each output here
end
You can check for :thumbnails like so:
if (thumbnails = output[:thumbnails])
# we've got thumbnails, deal with it here
end

Map object and nested object to model using Ruby on Rails

I have an object like
{"Result":[{
"Links":[{
"UrlTo":"http://www.example.com/",
"Visited":1364927598,
"FirstSeen":1352031217,
"PrevVisited":1362627231,
"Anchor":"example.com",
"Type":"Text",
"Flag":[],
"TextPre":"",
"TextPost":""
}],
"Index":0,
"Rating":0.001416,
"UrlFrom":"http://www.exampletwo.com",
"IpFrom":"112.213.89.105",
"Title":"Example title",
"LinksInternal":91,
"LinksExternal":51,
"Size":5735
}]}
And I have a model with all of the keys.
UrlTo, Visited, FirstSeen, PrevVisited, Anchor, Type, TextPre, TextPost, Index, Rating, UrlFrom, IpFrom, Title, LinksInternal, LinksExternal, Size
I understand how to save this to the database without this bit below...
"Links":[{
"UrlTo":"http://example.com/",
"Visited":1364927598,
"FirstSeen":1352031217,
"PrevVisited":1362627231,
"Anchor":"example.com",
"Type":"Text",
"Flag":[],
"TextPre":"",
"TextPost":""
}],
Not sure how to save it with a nested object as well.
I had a search on Google and SO and couldn't find anything, what is the correct way to do this? Should I move the nested object into the one above? I have no need for it to be nested...
Thanks in advance
it looks like you want to save links, so I would loop over the Result/Links in the json provided, and create a new hash based on the links.
I've pretended below that your json is in a file called input.json -- but you'd obviously just parse the text or use an existing JSON object
require 'json'
json = JSON.parse File.read("input.json")
links = json["Result"].map do |result|
result["Links"].map {|link| link }
end.flatten
hash = {"Links" => links}
puts hash
This creates the object:
{"Links"=>[{"UrlTo"=>"http://www.example.com/", "Visited"=>1364927598, "FirstSeen"=>1352031217, "PrevVisited"=>1362627231, "Anchor"=>"example.com", "Type"=>"Text", "Flag"=>[], "TextPre"=>"", "TextPost"=>""}]}

Ruby On Rails: Accessing Array?

I have an array stored in a variable temp which looks like this:
temp.inspect output :
[#"Marlana Letelier", "completed_at"=>nil, "status"=>"incomplete", "name"=>nil, "lead_move_date"=>"2012-06-17 00:00:00", "archive_time"=>nil, "stop_time"=>nil, "priority"=>"2", "assigned_to_user_firstname"=>"Vanessa", "notes"=>"", "created_by_id"=>nil, "id"=>"804005", "assigned_to_id"=>"1", "dn_email_id"=>nil, "outcomes_string"=>"other", "lead_id"=>"101139", "flavor"=>"PhonecallTask", "stringified_parameters"=>"{\n'purpose' => 'continued contact attempt',\n'phone_number' => '361-946-9905',\n}", "created_at"=>"2011-12-21 13:29:07", "start_time"=>"2012-04-04 17:00:00"}>]
temp.class specifies it as an array but temp[1] doesn't output anything.
How do I access the elements ?
EDIT:
1) Temp either had nothing, 1 object or multiple objects
2) Check for nil
3) Get each object out
4) access the attributes
Although your inspect output looks wrong (I think you're missing some text that came out in <...> tags) it looks like you have an array with a single item. Verify this assumption by outputting temp.length.
Since Arrays in Ruby are 0-indexed, try temp[0] or temp.first.

Resources