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
Related
first_response = [
{"xId" => "123", "yId" => "321"},
{"xId" => "x", "yId" => "y" }
]
first_response.each do |resp|
x_id = resp['xId']
y_id = resp['yId']
puts x_id.to_s
puts y_id.to_s
end
This gives me outputs
123
321
x
y
output hash I want to create is
{123=>{321}, x=>{y}}
first service: I have an array of hash that has two different ids example:(x_id and y_id) (there would be multiple pairs like that in the response)
I want to create a hash that should contain the matching pair of x_id and y_ids that we get from the first service with x_id's as the key for all the pairs.
If you know every hash in first_response is going to contain exactly two key/value pairs, you can extract their values and then convert that result into a hash (see Enumerable#to_h):
first_response.to_h(&:values)
# {"123"=>"321", "x"=>"y"}
Looks like this approach works, but I am not completely sure if that is right
first_response = [{"xId"=>"123","yId"=> "321"}, {"xId"=>"x","yId"=> "y"}]
h = {}.tap do |element|
first_response.each do |resp|
x_id = resp['xId']
y_id = resp['yId']
element[x_id] = y_id
end
end
puts h.to_s
# {"123"=>"321", "x"=>"y"}
This is the output array when I do
result = JSON.parse(response.body)
result.values.each {|element|
puts element
}
Result:
{"id"=>3, "code"=>"3", "name"=>"Market", "status"=>"A", "refcode"=>"001"}
{"id"=>4, "code"=>"4", "name"=>"Mall", "status"=>"A", "refcode"=>"002"}
From this array, I only want to get the name value. I tried this
puts result['data'][0]['name'] and it worked fine but I want to get all the name in the array
This is my expected output
Market
Mall
Try using Array#map and over each element, to access it's 'name' key, like:
p array.map { |element| element['name'] }
# ["Market", "Mall"]
I think it'd be something like:
result = JSON.parse(response.body)
result.values.map { |element| element['name'] }
# ["Market", "Mall"]
Since with each and puts you're only iterating and printing the hashes in the array, you could access the 'name' key from result.values.
I wont modify much. Since your name element is at position 3. access it like array because you are using values.each
result = JSON.parse(response.body)
result.values.each {|element|
puts element[2]
}
I've created the following hash keys with values parsed from PDF into array:
columns = ["Sen", "P-Hire#", "Emp#", "DOH", "Last", "First"]
h = Hash[columns.map.with_index.to_h]
=> {"Sen"=>0, "P-Hire#"=>1, "Emp#"=>2, "DOH"=>3, "Last"=>4, "First"=>5}
Now I want to update the value of each key with 6 equivalent values from another parsed data array:
rows = list.text.scan(/^.+/)
row = rows[0].tr(',', '')
#data = row.split
=> ["2", "6", "239", "05/05/67", "Harp", "Erin"]
I can iterate over #data in the view and it will list each of the 6 values. When I try to do the same in the controller it sets the same value to each key:
data.each do |e|
h.update(h){|key,v1| (e) }
end
=>
{"Sen"=>"Harper", "P-Hire#"=>"Harper", "Emp#"=>"Harper", "DOH"=>"Harper", "Last"=>"Harper", "First"=>"Harper"
So it's setting the value of each key to the last value of the looped array...
I would just do:
h.keys.zip(#data).to_h
If the only purpose of h is as an interim step getting to the result, you can dispense with it and do:
columns.zip(#data).to_h
There are several ways to solve this problem but a more direct and straight forward way would be:
columns = ["Sen", "P-Hire#", "Emp#", "DOH", "Last", "First"]
...
#data = row.split
h = Hash.new
columns.each_with_index do |column, index|
h[column] = #data[index]
end
Another way:
h.each do |key, index|
h[key] = #data[index]
end
Like I said, there are several ways of solving the issue and the best is always going to depend on what you're trying to achieve.
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.
I have a CSV file with two columns:
PPS_Id Amount
123 100
1234 150
I read data from this file and insert in a array using the code below:
CSV.foreach("filename.CSV", headers: true) do |row|
file_details << row.inspect # hash
end
I am then trying to push the data in the file_details into a hash with PPS_Id as key and Amount as Value, I am using the code below:
file_details_hash = Hash.new
file_details.each { |x|
file_details_hash[x['PPS_Id']] = x['Amount']
}
But when I print the result I get nothing just {"PPS_Id"=>"Amount"}
Can you please help
Your code, modified to work
You need to specify the column separator for your csv, and remove inspect.
require 'csv'
file_details = []
CSV.foreach("filename.CSV", headers: true, col_sep: "\s" ) do |row|
file_details << row
end
file_details_hash = Hash.new
file_details.each { |x|
file_details_hash[x['PPS_Id']] = x['Amount']
}
p file_details_hash
#=> {"123"=>"100", "1234"=>"150"}
It now returns what you expected to get.
Shorter solution
Read the csv, drop the first line (header) and convert to a Hash :
p CSV.read("filename.CSV", col_sep: "\s").drop(1).to_h
#=> {"123"=>"100", "1234"=>"150"}
First of all, you are collecting strings into an array (see String#inspect):
file_details << row.inspect
After that you call (sic!) String#[] on that strings:
x['PPS_Id'] #⇒ "PPS_Id", because string contains this substring
That said, your code has nothing but errors. You might achieve what you want with:
csv = CSV.parse(File.read("filename.CSV"), col_sep: "\s")
csv[1..-1].to_h
#⇒ {
# "123" => "100",
# "1234" => "150"
# }
Using inspect will save your CSV rows as strings, so obviously you won't be able get what you need. Instead try this:
file_details = CSV.read("filename.csv")
Read CSV directly will create an 2D array that you can then iterate over, which will look like this: [["PPS_Id", "Amount"], ["123", "100"], ["1234", "150"]]
From there you can slightly modify your approach:
file_details.each do |key, value|
file_details_hash[key] = value
end
To receive a hash like this: {"PPS_Id"=>"Amount", "123"=>"100", "1234"=>"150"}