Hash becomes array after post - ruby-on-rails

I have a hash in Ruby:
params[:test]={:name=>'sharing'}
restPost(url, params)
on the other end, I output the params:
render :json=>{ :params=>params[:test] }
I get the result:
{"params":["name", "sharing"] }
It seems the hash is turned into a array. What I want is:
{"params": {"name":"sharing"}}

One way to deal with this might be to convert the array back to a Hash with Hash[], e.g.:
a = ["name", "sharing"]
h = Hash[*a]

Related

How to get each value from hash of array?

I have a hash of array with key, values in ruby which I want to pass each value with key. I want to extract content using my hash. My code is :
def get_content
GetPageContent.new(#pdf.id, session[:selected_pages][#document.id.to_s])
end
in session[:selected_pages] I got like this
{"15"=>["001"], "24"=>["001","005"]}
In this first value is pdf id and second value is page number of that pdf.
I want this :
GetPageContent.new(#pdf.id, session[:selected_pages][#document.id.to_s])
I want to pass all values like this:
GetPageContent.new(15, 001)
GetPageContent.new(24, 001)
GetPageContent.new(24, 005)
How to map each key values from hash of array?
A simple nested loop will suffice:
session[:selected_pages].each do |pdf_id, page_numbers|
page_numbers.each { |page_number| GetPageContent.new(pdf_id, page_number) }
end
You can use something like this
hsh = {"15"=>["001"], "24"=>["001","005"]}
hsh.each(&->(page, pages){pages.each{|id| GetPageContent.new(id, page)}})
You could do something like this to get a simple array. h is your hash
pages = h.flat_map { |key, arr| ([key] * arr.size).zip(arr) }
=> [["15", "001"], ["24", "001"], ["24", "005"]]
pages.map! { |pdf_id, page_number| GetPageContent.new(pdf_id, page_number) }
session[:selected_pages]
.map{|k, v| [k].product(v)}.flatten(1)
# => [["15", "001"], ["24", "001"], ["24", "005"]]
The rest is up to you.

Splitting values in Hash

I have a Hash in the following format:
{"PPS_Id"=>["fe4d7c06-215a-48a7-966d-19ab58976548", "6e90208e-4ab2-4d44-bbaa-9a874bff095b"], "Amount"=>"[\"10000.000\", \"2374.000\"]"}
When I write this data into an excel get the following output.
I want to write the data into the Excel this way:
PPS_Id Amount
fe4d7c06-215a-48a7-966d-19ab58976548 10000.000
6e90208e-4ab2-4d44-bbaa-9a874bff095b 2374.000
How do I convert my current Hash to the below?
{PPS_Id"=>["fe4d7c06-215a-48a7-966d-19ab58976548","Amount"=>"10000.000"},{PPS_Id"=>["6e90208e-4ab2-4d44-bbaa-9a874bff095b","Amount"=>"2374.000"}
Can you please assist.
If you can modify your original hash from
hash = {"PPS_Id"=>["fe4d7c06-215a-48a7-966d-19ab58976548", "6e90208e-4ab2-4d44-bbaa-9a874bff095b"], "Amount"=>"[\"10000.000\", \"2374.000\"]"}
to
hash = {"PPS_Id"=>["fe4d7c06-215a-48a7-966d-19ab58976548", "6e90208e-4ab2-4d44-bbaa-9a874bff095b"], "Amount"=>["10000.000", "2374.000"]}
Note: the last value in the hash is an Array instead of a String.
Then, you can generate an Array of hashes on which you can iterate to fill your excel:
ary = hash.inject([]) do |r, (key, value)|
value.each_with_index do |e, i|
r[i] ||= {}
r[i][key] = e
end
r
end
ary # [{"PPS_Id"=>"fe4d7c06-215a-48a7-966d-19ab58976548", "Amount"=>"10000.000"}, {"PPS_Id"=>"6e90208e-4ab2-4d44-bbaa-9a874bff095b", "Amount"=>"2374.000"}]
If your hash really looks like this :
hash = {"PPS_Id"=>["fe4d7c06-215a-48a7-966d-19ab58976548", "6e90208e-4ab2-4d44-bbaa-9a874bff095b"],
"Amount"=>"[\"10000.000\", \"2374.000\"]"}
you can use scan to parse the floats first :
hash["Amount"] = hash["Amount"].scan(/[\d\-\.]+/)
Your hash will now look like :
{"PPS_Id"=>["fe4d7c06-215a-48a7-966d-19ab58976548", "6e90208e-4ab2-4d44-bbaa-9a874bff095b"],
"Amount"=>["10000.000", "2374.000"]}
To get the table you want, you could just transpose the hash values :
hash.values_at("PPS_Id", "Amount").transpose.each{|id, amount|
puts format("%s\t%.3f", id, amount)
}
It will output :
fe4d7c06-215a-48a7-966d-19ab58976548 10000.000
6e90208e-4ab2-4d44-bbaa-9a874bff095b 2374.000

passing array through Net::HTTP

I'm trying to pass an array through Net::HTTP to a ruby
def send_p
x = Net::HTTP.post_form(URI.parse('http://example_domain/example'), to_send)
render text: x
end
def to_send
{
param_a: "foo",
param_b: [1,2,3]
}
end
but when check the params in http://example_domain/example is getting me
{
"param_a"=>"foo",
"param_b"=>"3",
"action"=>"my_method",
"controller"=>"my_controller"
}
what can I do to receive the array in the proper way: [1,2,3]
Try using HTTParty:
x = HTTParty.post(URI.parse('http://example_domain/example'), to_send)
You can convert the array to string and then do the inverse when getting the params from the response.
Convert to String before to send it
param_b: [1,2,3].to_s
You will receive exactly as you sent it
"param_b"=>"[1,2,3]"
Convert it back to Array
eval(params[:param_b])
# => [1, 2, 3]

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"}

returning an array that contains an array and hash in ruby method?

HI
is it possible to return an array that contains an array and hash from a method in ruby?
i.e
def something
array_new = [another_thing, another_thing_2]
hash_map = get_hash()
return [array_new, hash_map]
end
and to retrieve the array:
some_array, some_hash = something()
thanks
Sure, that's perfectly possible and works exactly as in your example.
You will only ever be able to return one thing. What you are returning there is an array containing an array and a hash.
Ruby methods can be treated as if they return multiple values so you can collect the items in an array or return them as separate objects.
def something
array_new = Array.new
hash_new = Hash.new
return array_new, hash_new
end
a, b = something
a.class # Array
b.class # Hash
c = something
c.class # Array

Resources