how to convert the given string to array in rails - ruby-on-rails

I have the following Strings. I want them to convert into Arrays like below in rails
"[\"Winter\", \"Summer\", \"Spring\"]" to ["Winter", "Summer", "Spring"]
"[\"IELTS\", \"GRE\", \"PTE\", \"SAT\"]" to ["IELTS", "GRE", "PTE", "SAT"]
How can i convert these

You can do it with JSON.
require 'json'
string = "[\"Winter\", \"Summer\", \"Spring\"]"
JSON.parse(string)
=> ["Winter", "Summer", "Spring"]

just alternate solution (not safe) :
> string = "[\"Winter\", \"Summer\", \"Spring\"]"
> eval(string)
#=> ["Winter", "Summer", "Spring"]
Note: better option to parse with JSON

Related

New DateTime instead of String in ruby

I've got some issue with DateTime in Ruby
I've got line which looks like this (it's in .txt file)
DateTime.new(1979,1,1) DateTime.new(2012,3,29)
And my function to get this looks like this
def split_line
array = line.split(' ')
#date_of_birth = array[0]
#date_of_death = array[1]
end
But #date_of_birth and #date_of_death class are String. How can I get them as DateTime?
Assuming your string is in the correct format, then you're probably looking for:
#date_of_birth = array[0].to_datetime
#date_of_death = array[1].to_datetime
See here for more info:
https://apidock.com/rails/String/to_datetime
This:
DateTime.new(1979,1,1) DateTime.new(2012,3,29)
Is not code. What do you expect that to do?
If you want two DateTimes as a space-separated string, do something like:
"#{DateTime.new(1979,1,1)} #{DateTime.new(2012,3,29)}"
When you have something like #{...} inside a set of double quotation marks (they must be double, not single quotation marks), it's called string interpolation. Learn it. Love it. Live it.
But, for the life of me, I don't know why you wouldn't do:
[DateTime.new(1979,1,1), DateTime.new(2012,3,29)]
Which gives you an array, so no split needed. Just:
def split_line
#date_of_birth = array[0]
#date_of_death = array[1]
end
If you want DateTime values, grab the numbers and create them:
require 'date'
'DateTime.new(1979,1,1) DateTime.new(2012,3,29)'.split.map { |s|
DateTime.new(*s.scan(/\d+/).map(&:to_i) )
}
# => [#<DateTime: 1979-01-01T00:00:00+00:00 ((2443875j,0s,0n),+0s,2299161j)>,
# #<DateTime: 2012-03-29T00:00:00+00:00 ((2456016j,0s,0n),+0s,2299161j)>]
The values aren't DateTime though, they're Dates:
'DateTime.new(1979,1,1) DateTime.new(2012,3,29)'.split.map { |s|
Date.new(*s.scan(/\d+/).map(&:to_i) )
}
# => [#<Date: 1979-01-01 ((2443875j,0s,0n),+0s,2299161j)>,
# #<Date: 2012-03-29 ((2456016j,0s,0n),+0s,2299161j)>]
Breaking it down:
'DateTime.new(1979,1,1) DateTime.new(2012,3,29)'.split # => ["DateTime.new(1979,1,1)", "DateTime.new(2012,3,29)"]
.map { |s|
Date.new(
*s.scan(/\d+/) # => ["1979", "1", "1"], ["2012", "3", "29"]
.map(&:to_i) # => [1979, 1, 1], [2012, 3, 29]
)
}
# => [#<Date: 1979-01-01 ((2443875j,0s,0n),+0s,2299161j)>,
# #<Date: 2012-03-29 ((2456016j,0s,0n),+0s,2299161j)>]
* (AKA "splat"), used like this, explodes an array into its elements, which is useful when you have an array but the method only takes separate parameters.
The bigger question is why you're getting values like that in a text file.

Convert string representation of nested array to Array

I have a string representation of array:
val1 = "[[\":one\", \":two\"], [\":four\", \":one\"]]"
What is the best way to convert it into:
val2 = [[:one,:two], [:four, :one]]
The dimension of array could be 25 x 25.
Use JSON.parse:
require 'json'
val2 = JSON.parse val1
# => [[":one", ":two"], [":four", ":one"]]
or you can convert them to symbols like this:
val2.map{|a,b| [a.sub(/^:/,'').to_sym, b.sub(/^:/,'').to_sym]}
# => [[:one, :two], [:four, :one]]
You can use YAML.load:
require 'yaml'
YAML.load(val1.delete ':').map{|x| x.map(&:to_sym)}
# => [[:one, :two], [:four, :one]]
Demonstration
And I guess I should be ready for downvotes, but you can use eval:
eval(val1).map{|x| x.map(&method(:eval))}
# => [[:one, :two], [:four, :one]]
Demonstration
eval val1.tr('"','') #=> [[:one, :two], [:four, :one]]
eval val1.gsub '"','' #=> [[:one,:two], [:four, :one]]
val1 = "[[\":one\", \":two\"], [\":four\", \":one\"]]"
puts val1.unpack('ZZ')
Descrition:
'unpack' decodes the string (which may contain binary data). According to the format string, it is returning an array of each value extracted. In the above code, Z stands for null terminated string.

Array values to keys?

I am parsing some XML to JSON and then serving this on http://floating-gorge-9520.herokuapp.com/currencies.
I want to display the data so the values for currency are the keys and the values for rate then become the values for the new currency data.
For example:
USD: 1
GBP: 0.5
What is the best way of doing this?
Using two currencies for simplicity:
require 'json'
a = [{"currency"=>"USD", "rate"=>"1.3707"},
{"currency"=>"JPY", "rate"=>"140.50"}]
Hash[a.map { |h| [h['currency'],h['rate'].to_f] }]
# => {"USD"=>1.3707, "JPY"=>140.5}
Just append a .to_json on the last statement to get the JSON string.
Check this out
require 'json'
a = {}
json = '[{"currency":"USD","rate":"1.3707"},{"currency":"JPY","rate":"140.50"},{"currency":"BGN","rate":"1.9558"},{"currency":"CZK","rate":"27.368"},{"currency":"DKK","rate":"7.4625"},{"currency":"GBP","rate":"0.82183"},{"currency":"HUF","rate":"311.89"},{"currency":"LTL","rate":"3.4528"},{"currency":"PLN","rate":"4.1661"},{"currency":"RON","rate":"4.5222"},{"currency":"SEK","rate":"8.9953"},{"currency":"CHF","rate":"1.2195"},{"currency":"NOK","rate":"8.3670"},{"currency":"HRK","rate":"7.6685"},{"currency":"RUB","rate":"49.0415"},{"currency":"TRY","rate":"3.0097"},{"currency":"AUD","rate":"1.5283"},{"currency":"BRL","rate":"3.2577"},{"currency":"CAD","rate":"1.5304"},{"currency":"CNY","rate":"8.3495"},{"currency":"HKD","rate":"10.6313"},{"currency":"IDR","rate":"16097.50"},{"currency":"ILS","rate":"4.8062"},{"currency":"INR","rate":"85.1580"},{"currency":"KRW","rate":"1469.53"},{"currency":"MXN","rate":"18.2348"},{"currency":"MYR","rate":"4.5158"},{"currency":"NZD","rate":"1.6558"},{"currency":"PHP","rate":"61.092"},{"currency":"SGD","rate":"1.7376"},{"currency":"THB","rate":"44.603"},{"currency":"ZAR","rate":"15.1355"}]';
JSON.parse(json).each { |x| a[x['currency']] = x['rate'] }
print a

Converting http_params to hash

I can obtain an array from the string
http_params="created_end_date=2013-02-28&created_start_date=2013-01-01&page_size=50&offset=0&order_id=0D1108211501118%0D%0A0D11108211501118%0D%0Ac%0D%0AD%0D%0ADK212071409743%0D%0AKK30109110100%0D%0AKK30111140300%0D%0AKK30111140400%0D%0AKK30115120100%0D%0AKK30115150100&page_number=1"
So I did myarray=http_params.split("&"):
myarray=["created_end_date=2013-02-28", "created_start_date=2013-01-01", "page_size=50", "offset=0", "order_id=0D1108211501118%0D%0A0D11108211501118%0D%0Ac%0D%0AD%0D%0ADK212071409743%0D%0AKK30109110100%0D%0AKK30111140300%0D%0AKK30111140400%0D%0AKK30115120100%0D%0AKK30115150100", "page_number=1"]
I need to convert this to a hash myhash, so that I can make a Rest Client post call for myhash.to_json. Basically it should be key,value pairs like:
{:created_end_date=>"2013-02-28",:created_start_date=>"2013-01-01"....}
I know that the inverse operation can be done like this:
http_params = myhash.map{|k,v| "#{k}=#{v}"}.join('&')
but I am unable to come up with neat code for this.
What's the best way I should go about this?
require 'cgi'
hash = CGI::parse http_params
Or you can use:
hash = Rack::Utils.parse_nested_query http_params
Which does not return the values as arrays.
With pure Ruby methods, you can convert your string into a Hash as follows:
"a=1&b=2".split('&').map { |h| Hash[*h.split("=")] }
=> [{"a"=>"1"}, {"b"=>"2"}]
A blog post how to operate on Ruby collections is here: http://thinkingonthinking.com/map-reduce-in-ruby/
To get symbols as keys, a small additional step is necessary:
"a=1&b=2".split('&').map { |h| hs = h.split("="); Hash[hs[0].to_sym, hs[1]] }
=> [{:a=>"1"}, {:b=>"2"}]
As last step, a merge of the inner Hash elements has to be done. This can be done like:
"a=1&b=2".split('&').map { |h| hs = h.split("="); Hash[hs[0].to_sym, hs[1]] }.inject({}) { |s, h| s.merge(h) }
=> {:a=>"1", :b=>"2"}

Get a particular key value from json in ruby

[
"KEY1":{"SUB_KEY1" : "VALUE1","SUB_KEY2" : "VALUE2"},
"KEY2":{"SUB_KEY1" : "VALUE1","SUB_KEY2" : "VALUE2"}
]
The above is my json object which is coming as a response.
How do I get SUB_KEY1 of KEY1 and SUB_KEY1 of KEY2 in Ruby on Rails?
Thank you.
You need to parse the JSON object into a ruby hash. Assuming your JSON response is called res:
require 'json'
obj = JSON.parse(res)
sv1 = obj['KEY1']['SUB_KEY1']
etc.
parsed_json = ActiveSupport::JSON.decode(your_json_string)
will parse your string as
[{"KEY1"=>{"SUB_KEY1"=>"VALUE1", "SUB_KEY2"=>"VALUE2"}}, {"KEY2"=>{"SUB_KEY1"=>"VALUE1", "SUB_KEY2"=>"VALUE2"}}]
You should be able to access it using something like parsed_json[1]["KEY2"]["SUB_KEY1"]
You need to parse JSON data first. Then loop over the JSON object to access the key as follow:
#response = JSON.parse(HTTParty.get(your_url).body)
#response["data"].each do |key|
puts data[0][key]
puts data[0][key2]
end

Resources