How do I extract a value from this Ruby hash? - ruby

I'm using the Foursquare API, and I want to extract the "id" value from this hash
[{"id"=>"4fe89779e4b09fd3748d3c5a", "name"=>"Hitcrowd", "contact"=>{"phone"=>"8662012805", "formattedPhone"=>"(866) 201-2805", "twitter"=>"hitcrowd"}, "location"=>{"address"=>"1275 Glenlivet Drive", "crossStreet"=>"Route 100", "lat"=>40.59089895083072, "lng"=>-75.6291255071468, "postalCode"=>"18106", "city"=>"Allentown", "state"=>"Pa", "country"=>"United States", "cc"=>"US"}, "categories"=>[{"id"=>"4bf58dd8d48988d125941735", "name"=>"Tech Startup", "pluralName"=>"Tech Startups", "shortName"=>"Tech Startup", "icon"=>"https://foursquare.com/img/categories/shops/technology.png", "parents"=>["Professional & Other Places", "Offices"], "primary"=>true}], "verified"=>true, "stats"=>{"checkinsCount"=>86, "usersCount"=>4, "tipCount"=>0}, "url"=>"http://www.hitcrowd.com", "likes"=>{"count"=>0, "groups"=>[]}, "beenHere"=>{"count"=>0}, "storeId"=>""}]
When I try to extract it by using ['id'], I get this error can't convert Symbol into Integer. How do I extract the value using ruby? Also, how do I do this for multiple hashes extracting the "id" value each time?
Please pardon my inexperience. Thanks!

It's wrapped in an array, that's what the [ and ] mean on the start and end. But it also looks like this array only one object in it, which is the hash you really want.
So assuming you want the first object in this array:
mydata[0]['id'] # or mydata.first['id'] as Factor Mystic suggests
But usually when an API returns an Array there is a reason (it might return many results instead of just one), and naively plucking the first item from it my not be what you want. So be sure you are getting the kind of data you really expect before hard coding this into your application.

For multiple hashes, if you want to do something with the id (run a procedure of some kind) then
resultsArray.each do |person|
id = person["id"] #then do something with the id
end
If you want to just get an array containing the ids then
resultsArray.map{|person| person["id"]}
# ["4fe89779e4b09fd3748d3c5a", "5df890079e4b09fd3748d3c5a"]
To just grab the one item from the array, see Alex Wayne's answer

To get an array of ids, try: resultsArray.map { |result| result["id"] }

Related

Access value from a Netsuite hash, Enumerator

Hi I am trying to extract a value from a Netsuite hash inside custom fields, and some others, which typically look like this - `
"custbody_delivery_ticket_number"=>
{
"script_id"=>"custbody_delivery_ticket_number",
"internal_id"=>"2701",
"type"=>"platformCore:DateCustomFieldRef",
"attributes"=> {
"value"=>"123abc"
}
}` and want the value of it inside of attributes.
Have tried many different ways, but one in particular -
delivery_ticket_number: "#{netsuite_sales_orders.custom_field_list.custom_fields.select['custbody_nef_meter_ticket_number']['attributes']['value']}",
throws error for class Enumerator, NoMethodError: undefined method `[]' for #Enumerator:0x00005589ec778730 which indicates may be getting close, but doing something wrong.
If anyone has any idea how to get values from these kind of hashes?
(Am told by the system admin that it is the correct custbody identifier)
Many Thanks
Eventually fixed this, grabbing Netsuite custom fields with a select of script_id by name,and map as below:
delivery_date:netsuite_sales_order.custom_fields_list.custom_fields.select { |field| field.script_id == 'custbody_delivery_date' }.map { |field| field.value }.first
First selecting the script_id by unique name, then mapping to the value. Was able to get any custom field like this, preferable as they can move and might not have the same index if use an index to grab them, fetching an incorrect value. This way ensures getting the correct data even if the item is moved up or down in the custom fields list.
Thanks for everyones help!

How can i sort an arrays of hashes in ruby

this is the code i tried to sort it by name,email,country,comments.first i tried sorting by names
array_of_hashes=[
{"Name"=>"Akash","Email"=>"akash85#gmail.com","Country"=>"India",'Comments'=>"9898984523"},
{"Email"=>"rahul#hotmail.com","Country"=>"Srilanka","Name"=>"Rahul"},
{"Country"=>"India", "Comments"=>"3455358782","Email"=>"veera#gmail.com","Name"=>"Veera"},
{"Name"=>"Akash","Country"=>"India", "Email"=>"akash37#yahoo.com", "Comments"=>"8898788932"}
]
puts array_of_hashes.sort_by { |element| element.keys(&:Name)}
but the displayed output is not as i expected,it prints the same which i mentioned above.
i expected to code the final output should be like this
Name Email Country Comments
Akash akash37#live.com India 8898788932
Akash akash85#gmail.com India 9898984523
Rahul rahul#hotmail.com Srilanka
Veera veera#gmail.com India 3455358782
Help me to resolve these.Thanks in advance!
You should look at what element.keys(&:Name) evaluates to in the block that you're passing to #sort_by. All methods in Ruby can be given a block, you can pass it even if the method doesn't use it. Hash#keys doesn't use the block so element.keys(&:Name) is the same as element.keys and you end up trying to sort by the array ['Name', 'Email', 'Country', 'Comments'].
If you want to sort by the name, say so:
hash.sort_by { |element| element['Name'] }
Keep in mind that your keys are strings so you want element['Name'] rather than element[:Name]. I'd also recommend that you don't call your array of hashes hash, that's a little confusing.
not_a_hash = [
{"Name"=>"Akash","Email"=>"akash85#gmail.com","Country"=>"India",'Comments'=>"9898984523"},
{"Email"=>"rahul#hotmail.com","Country"=>"Srilanka","Name"=>"Rahul"},
{"Country"=>"India", "Comments"=>"3455358782","Email"=>"veera#gmail.com","Name"=>"Veera"},
{"Name"=>"Akash","Country"=>"India", "Email"=>"akash37#yahoo.com", "Comments"=>"8898788932"}
]
sorted_values = not_a_hash.map{|h| h.values_at("Name", "Email", "Country", "Comments")}.sort

Ruby Array sort_by value in variable

I would like to sort Ruby Array by key in variable, but I don't know how.
Situation
my_arr.sort_by {|record| [record.year]}
Will sort by a year of the record. But I want to sort by author, label, etc. And this sort type is stored in a variable like a String. So I need to evaluate the filter like
my_arr.sort_by {|record| [record."something_in_the_var"]}
Of course, I have fixed filters. But still figuring out how to do it properly.
Thanks for tips
This is what send does
str = "label"
arr.sort_by{|rec| rec.send(str) }
send is defined on BasicObject, so every object has it.
you can use something like
sort_by_this = "label"
my_arr.sort_by {|record| [record[sort_by_this]]}

Converting multiple arrays into a single hash

I'm working on a configuration file parser and I need help parsing key: value pairs into a hash.
I have data in the form of: key: value key2: value2 another_key: another_value.
So far I have code in form of
line = line.strip!.split(':\s+')
which returns an array in the form of
["key:value"]["key2: value2"]["another_key: another_value"]
How can I turn these arrays into a single hash in the form of
{key=>value, key2=>value2, another_key=>another_value}
I'm not sure if the key:value pairs need to be in the form of a string or not. Whatever is easiest to work with.
Thanks for your help!
This is the solution I found:
line = line.strip.split(':')
hash = Hash[*line]
which results in the output{"key"=>"value"}, {"key2"=>"value2"}
Very very close to Cary's solution:
Hash[*line.delete(':').split]
Even simpler:
Hash[*line.gsub(':',' ').split]
# => {"key"=>"value", "key2"=>"value2", "another_key"=>"another_value"}
Assuming the key and value are single words, I'd probably do something like this:
Hash[line.scan(/(\w+):\s?(\w+)/)]
You can change the regex if it's not quite what you are looking for.

Ruby: How can I make these objects the same?

So I have the following hashes/arrays:
{"number"=>[{"tracking"=>"1Z81E74W0393736553", "notes"=>"Example note"}, {"tracking"=>"9102901001301227214058"}]}
{"number"=>{"tracking"=>"1Z81E74W0393736553", "notes"=>"Example note"}}
That first hash has an array for number while the second one doesn't.
It's wreaking havoc trying to loop through the data (specifically when there's only one tracking/notes combo).
Ultimately I'm wanting to be able to do an each loop on each tracking/notes combo.
h1={"number"=>[{"tracking"=>"1Z81E74W0393736553", "notes"=>"Example note"}, {"tracking"=>"9102901001301227214058"}]}
h2={"number"=>{"tracking"=>"1Z81E74W0393736553", "notes"=>"Example note"}}
[h1["number"]].flatten
=> [{"notes"=>"Example note", "tracking"=>"1Z81E74W0393736553"}, {"tracking"=>"9102901001301227214058"}]
[h2["number"]].flatten
=> [{"notes"=>"Example note", "tracking"=>"1Z81E74W0393736553"}]
Now, each will be an array of hashes and you can use each to iterate through them.
Something like this?
hash["number"] = [ hash["number"] ] unless hash["number"].kind_of?(Array)

Resources