ruby - how can I access an variable - ruby

I have this array:
{
:details=> [
{
"account" =>"",
"address" =>"",
"category" =>"send",
"amount" =>0.0,
"fee" =>0.0
},
{
"account" =>"payment",
"address" =>"SXX5kpEyF8w1oK913wVg2ZbJWpLmWnCgAU",
"category" =>"receive",
"amount" =>1.0
}
]
}
How can I access the second "address" element in ruby? When I do
address: detail[:address]
I get only the first one (which is empty).

How about:
data = {
:details=> [
{
"account" =>"",
"address" =>"",
"category" =>"send",
"amount" =>0.0,
"fee" =>0.0
},
{
"account" =>"payment",
"address" =>"SXX5kpEyF8w1oK913wVg2ZbJWpLmWnCgAU",
"category" =>"receive",
"amount" =>1.0
}
]
}
And then(Because, you never know the sequence of Hashes inside Array):
data[:details].detect{|d| !d['address'].empty? }['address']

Just address the second element of array
obj = {
:details => [
{
"account" =>"",
"address" =>"",
"category" =>"send",
"amount" =>0.0,
"fee" =>0.0
},
{
"account" =>"payment",
"address" =>"SXX5kpEyF8w1oK913wVg2ZbJWpLmWnCgAU",
"category" =>"receive",
"amount" =>1.0
}
]
}
obj[:details][1]['address']
Here is online REPL: http://repl.it/ZZm

Using the inject method you can get all of them like this:
[21] pry(main)> results = []
=> []
[22] pry(main)> json[:details].inject { |sum, k| results << k["address"] }
=> [["SXX5kpEyF8w1oK913wVg2ZbJWpLmWnCgAU"]]

Related

Proper way to Parse a Payload in Ruby

I have the following payload:
[{:payload=>
"{\"user\":\"test\",\"job\":\"Test\",\"username\":\"Bob\",\"blocks\":[{\"type\":\"section\",\"text\":{\"type\":\"mrkdwn\",\"text\":\"this is the title\"}},{\"type\":\"context\",\"elements\":[{\"type\":\"mrkdwn\",\"text\":\"Test\"}]},{\"type\":\"divider\"}]}"}]
I'm trying to figure out how to extract it. I tried
JSON.parse(response)
But I get the following error
TypeError: no implicit conversion of Hash into String
How can I extract this value to something where I can do something like:
response.job == "test" ?
Let's assume that you meant to say:
response = [{:payload => "{\"user\":\"test\",\"job\":\"Test\",\"username\":\"Bob\",\"blocks\":[{\"type\":\"section\",\"text\":{\"type\":\"mrkdwn\",\"text\":\"this is the title\"}},{\"type\":\"context\",\"elements\":[{\"type\":\"mrkdwn\",\"text\":\"Test\"}]},{\"type\":\"divider\"}]}"}]
Then response is an array with one element. That one element is a hash. You would thus access the payload with:
payload = JSON.parse(response.first[:payload])
=> {
"user" => "test",
"job" => "Test",
"username" => "Bob",
"blocks" => [
[0] {
"type" => "section",
"text" => {
"type" => "mrkdwn",
"text" => "this is the title"
}
},
[1] {
"type" => "context",
"elements" => [
[0] {
"type" => "mrkdwn",
"text" => "Test"
}
]
},
[2] {
"type" => "divider"
}
]
}
The payload object is then a hash and its child elements can be accessed using the standard [] call:
job = payload['job']
=> "Test"

How find a nth node value using ruby

I have a JSON response tree like structure
{
"id":""
"node": [
{
"id":""
"node": [
{
"id":""
"node":[]
}
]
}
]
}
How could I get the last id value, it's just example it may contain n number of loops.
h = {
"id" => "1",
"node" => [
{
"id" => "2",
"node" => [
{
"id" => "3",
"node" => []
}
]
}
]
}
▶ λ = ->(h) { h['node'].empty? ? h['id'] : λ.(h['node'].last) }
#⇒ #<Proc:0x00000002f4b490#(pry):130 (lambda)>
▶ λ.(h)
#⇒ "3"
Maybe this method will helps you. You can call recursion method with sub hash.
h = {
"id" => "1",
"node" => [
{
"id" => "2",
"node" => [
{
"id" => "3",
"node" => []
}
]
}
]
}
def get_last_node(h)
if Array === h['node'] && !h['node'].empty?
h['node'].each do |node_h|
id = send(__callee__, node_h)
return id if id
end
nil
else
h['id']
end
end
get_last_node(h)
# => 3
Similar to #mudasobwa's answer:
def get_last_node(h)
h["node"].empty? ? h["id"] : get_last_node(h["node"].first)
end
get_last_node(h)
#=> 3

How do I convert an Array with a JSON string into a JSON object (ruby)

I have an Array whose content is as follow:
[
[0] {
"name" => “Mark”,
"id" => “01”,
"description" => “User”,
},
[1] {
"name" => “John”,
"id" => “02”,
"description" => “Developer”,
}
]
Note: right now each item of the Array is a Hash (not a string). That is to say that if I do puts myarray[0].class I get hash in return.
I would like to be able to create an object that I can reference as object[i].field.
For example I'd like to be able to get "Mark" by calling object[0].name or get "Developer" by calling object[1].description.
Is this possible? I have tried to leverage the .to_json method against my array but it doesn't quite give me what I need.
Thanks.
You can do use Struct to meet your need.
array = [
{
"name" => "Mark",
"id" => "01",
"description" => "User",
},
{
"name" => "John",
"id" => "02",
"description" => "Developer",
}
]
Customer = Struct.new(:name, :id, :description)
array_of_customers = array.map { |hash| Customer.new(*hash.values) }
array_of_customers[1].name # => "John"
array_of_customers[1].description # => "Developer"

How do I access JSON array data?

I have the following array:
[ { "attributes": {
"id": "usdeur",
"code": 4
},
"name": "USD/EUR"
},
{ "attributes": {
"id": "eurgbp",
"code": 5
},
"name": "EUR/GBP"
}
]
How can I get both ids for futher processing as output?
I tried a lot but no success. My problem is I always get only one id as output:
Market.all.select.each do |market|
present market.id
end
Or:
Market.all.each{|attributes| present attributes[:id]}
which gives me only "eurgbp" as a result while I need both ids.
JSON#parse should help you with this
require 'json'
json = '[ { "attributes": {
"id": "usdeur",
"code": 4
},
"name": "USD/EUR"
},
{ "attributes": {
"id": "eurgbp",
"code": 5
},
"name": "EUR/GBP"
}]'
ids = JSON.parse(json).map{|hash| hash['attributes']['id'] }
#=> ["usdeur", "eurgbp"]
JSON#parse turns a jSON response into a Hash then just use standard Hash methods for access.
I'm going to assume that the data is JSON that you're parsing (with JSON.parse) into a Ruby Array of Hashes, which would look like this:
hashes = [ { "attributes" => { "id" => "usdeur", "code" => 4 },
"name" => "USD/EUR"
},
{ "attributes" => { "id" => "eurgbp", "code" => 5 },
"name" => "EUR/GBP"
} ]
If you wanted to get just the first "id" value, you'd do this:
first_hash = hashes[0]
first_hash_attributes = first_hash["attributes"]
p first_hash_attributes["id"]
# => "usdeur"
Or just:
p hashes[0]["attributes"]["id"]
# => "usdeur"
To get them all, you'll do this:
all_attributes = hashes.map {|hash| hash["attributes"] }
# => [ { "id" => "usdeur", "code" => 4 },
# { "id" => "eurgbp", "code" => 5 } ]
all_ids = all_attributes.map {|attrs| attrs["id"] }
# => [ "usdeur", "eurgbp" ]
Or just:
p hashes.map {|hash| hash["attributes"]["id"] }
# => [ "usdeur", "eurgbp" ]
JSON library what using Rails is very slowly...
I prefer to use:
gem 'oj'
from https://github.com/ohler55/oj
fast and simple! LET'S GO!

Ruby: including a hash inside another hash

I have the following hash:
EMAIL_PWD_HASH = Hash.new
EMAIL_PWD_HASH[ "email" ] = { "label" => EMAIL_STR, "type" => "email_field" }
EMAIL_PWD_HASH[ "password" ] = { "label" => PWD_STR, "type" => "password_field" }
and the following hash:
NEW_USER_HASH = Hash.new
NEW_USER_HASH[ "first" ] = { "label" => FIRST_STR, "type" => "text_field" }
NEW_USER_HASH[ "last" ] = { "label" => LAST_STR, "type" => "text_field" }
NEW_USER_HASH[ "title" ] = { "label" => TITLE_STR, "type" => "text_field" }
NEW_USER_HASH[ "bio" ] = { "label" => BIO_STR, "type" => "text_field" }
I would like to add email and password to NEW_USER_HASH after last and before bio. What is the syntax for adding EMAIL_PWD_HASH (the order is important)?
NEW_USER_HASH.merge!(EMAIL_PAD_HASH)
Note also that hashes in ruby are not ordered.
I don't know how to do what you asked, and I doubt it's possible, but here's a quick and dirty way to do what you need:
NEW_USER_HASH['email'] = EMAIL_PWD_HASH['email']
NEW_USER_HASH['password'] = EMAIL_PWD_HASH['password']
NEW_USER_HASH['bio'] = NEW_USER_HASH.delete('bio') # deletes bio and reinsert in the end
email and password are now after last and before bio, as you asked. :)

Resources