Generate a Key, Value JSON object from a Ruby Object Array - ruby-on-rails

I have a Ruby array of students. Student class has attributes id, name and age.
students = [
{id:"id1",name:"name1",age:"age1"},
{id:"id2",name:"name2",age:"age2"},
{id:"id3",name:"name3",age:"age3"}
]
I want to create a JSON key value object from this array as follows.
json_object = {id1:name1, id2:name2, id3:name3}

input = [ {id:"id1",name:"name1",age:"age1"},
{id:"id2",name:"name2",age:"age2"},
{id:"id3",name:"name3",age:"age3"}]
require 'json'
JSON.dump(input.map { |hash| [hash[:id], hash[:name]] }.to_h)
#⇒ '{"id1":"name1","id2":"name2","id3":"name3"}'

Give this a go:
students = [
{id:"id1",name:"name1",age:"age1"},
{id:"id2",name:"name2",age:"age2"},
{id:"id3",name:"name3",age:"age3"}
]
json_object = students.each_with_object({}) do |hsh, returning|
returning[hsh[:id]] = hsh[:name]
end.to_json
In console:
puts json_object
=> {"id1":"name1","id2":"name2","id3":"name3"}

Your data is all identical, but if you wanted to generate a hash that took the value of students[n][:id] as keys and students[n][:name] as values you could do this:
student_ids_to_names = students.each_with_object({}) do |student, memo|
memo[student[:id]] = student[:name]
end
For your data, you'd end up with only one entry as the students are identical: { "id1" => "name1" }. If the data were different each key would be unique on :id.
Once you have a hash, you can call json_object = students_ids_to_names.to_json to get a JSON string.

Related

Make new array in controller by finding id

I have an array with Product Ids and Color HEX Codes
Input:
#campaign.selectedproducts
Output:
["2,333333","1,333333",4,444444"]
I'm trying to make a new array with all of the product data by finding it with id:
#selectedgifts = #campaign.selectedproducts.collect [{|i| Product.find(i) }, |i| i.split(',').last]
Array should output
["Product Object, HEX code", "Product Object, HEX code"]
¿Any help?
Thanks!
You can try with group_by method like below:
#campaign.selectedproducts.group_by(&:color_code).transform_values{|val| val.pluck(:id).uniq}
Converting Product object to string is not what you want i guess. So i suggest you storing each element as hash instead of string.
#campaign.selectedproducts.map do |string|
id, hex_code = string.split(',')
product = Product.find(id)
{ product => hex_code }
end
Edit: Or you can store each element as array like this:
#campaign.selectedproducts.map do |string|
id, hex_code = string.split(',')
product = Product.find(id)
[product, hex_code]
end

Ruby creating a new hash from an array of key, value

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

How to return a hash containing an array of file names for each owner name?

There is a hash named "files" as following :
files = {
'file1.txt' => 'John',
'file2.rb' => 'Andrew',
'file3.txt' => 'John'
}
Expected result:
A method that takes this hash as argument and return the hash containing the array of files for
respective owner. For e.g
{
'John' => ['file1.txt','file3.txt'],
'Andrew' => ['file2.rb']
}
Here you want to iterate over the file hash and for each key value pair you need to check if it already exists in your new hash, then you just want to add the file name to the array or you create a new key value pair.
def change_hash(file_hash)
new_hash = {}
file_hash.each do |file_name, person|
if new_hash[person]
new_hash[person] << file_name
else
new_hash[person] = [file_name]
end
end
new_hash
end
If you struggle with this, you want to look on how you can manipulate hashes (and arrays) in Ruby. Let me know if you have any more questions.
files.
group_by(&:last). # {"John"=>[["file1.txt", "John"], ["file3.txt", "John"]], "Andrew"=>[["file2.rb", "Andrew"]]}
transform_values { |v| v.map(&:first) } # {"John"=>["file1.txt", "file3.txt"], "Andrew"=>["file2.rb"]}

Ruby convert all values in a hash to string

I have the following snippet of code to fetch certain columns from the db:
#data = Topic.select("id,name").where("id in (?)",#question.question_topic.split(",")).map(&:attributes)
In the resulting Array of Hashes which is :
Current:
#data = [ { "id" => 2, "name" => "Sports" }]
To be changed to:
#data = [ { "id" => "2", "name" => "Sports" }]
I want to convert "id" to string from fixnum. Id is integer in the db. What is the cleanest way to do this?
Note: After using .map(&:attributes) it is not an active record relation.
You can do it with proper map usage:
topics = Topic.select("id,name").where("id in (?)",#question.question_topic.split(","))
#data = topics.map do |topic|
{
'id' => topic.id.to_s,
'name' => topic.name
}
end
What you're looking for is simply
#data.each { |obj| obj["id"] = obj["id"].to_s }
There isn't really a simpler way (I think that's straightforward enough anyway).
Going by the title which implies a different question - converting every value in the hash to a string you can do this:
#data.each do |obj|
obj.map do |k, v|
{k => v.to_s}
end
end
Just leaving that there anyway.
You can use Ruby's #inject here:
#data.map do |datum|
new_datum = datum.inject({}) do |converted_datum, (key, value)|
converted_datum[key] = value.to_s
converted_datum
end
end
This will work to convert all values to strings, regardless of the key.
If you are using Rails it can be even cleaner with Rails' #each_with_object:
#data.map do |datum|
datum.each_with_object({}) do |(key, value), converted_datum|
converted_datum[key] = value.to_s
end
end
This will iterate all the key names in the hash and replace the value with the #to_s version of the datum associated with the key. nil's converted to empty strings. Also, this assumes you don't have complex data within the hash like embedded arrays or other hashes.
def hash_values_to_string(hash)
hash.keys.each {|k| hash[k]=hash[k].to_s}; hash
end

How to insert an array to an existing hash array in Ruby?

I have a current array of the below hash map, i have another array that i would like to insert into each hash by matching on the id.
{"url"=>"http://ubuntu64:1990/getpages",
"id"=>"32794",
"version"=>"2",
"title"=>"Creating a page",
"space"=>"test",
"parentId"=>"32782",
"permissions"=>"0"}
The other array i want to add the 'imageurl' key/value based on the id, so something like (if id == id insert 'imageurl'/'someurl.jpg}
{"id"=>"32794", "imageurl" => "someurl.jpg}
array = [...] #Declare your array with the "big" hashes here
array2 = [...] #Declare your array with the hash containing the imageurl key here
array.each do |a|
array2.each do |a2|
if a[:id] == a2[:id]
a[:imageurl] = a2[:imageurl]
break #We found it
end
end
end
Should do the trick ... maybe there's a smarter way to do it though

Resources