From a model that returns all the values from a table, how would I convert that to a hash of name value pairs
{column_value => column_value}
e.g.
[{:id => 1, :name => 'first'}, {:id => 2, :name => 'second'}, {:id => 3, :name => 'third'}]
to (specifying :id and :name)
{'first' => 1, 'second' => 2, 'third' => 3}
You can do it in one line with inject:
a = [{:id => 1, :name => 'first'}, {:id => 2, :name => 'second'}, {:id => 3, :name => 'third'}]
a.inject({}) { |sum, h| sum.merge({ h[:name] => h[:id]}) }
# => {"third" => 3, "second" => 2, "first" => 1}
The following approach is reasonably compact, yet still readable:
def join_rows(rows, key_column, value_column)
result = {}
rows.each { |row| result[row[key_column]] = row[value_column] }
result
end
Usage:
>> rows = [{:id => 1, :name => 'first'}, {:id => 2, :name => 'second'}, {:id => 3, :name => 'third'}]
>> join_rows(rows, :name, :id)
=> {"third"=>3, "second"=>2, "first"=>1}
Or, if you want a one-liner:
>> rows.inject({}) { |result, row| result.update(row[:name] => row[:id]) }
=> {"third"=>3, "second"=>2, "first"=>1}
o = Hash.new
a = [{:id => 1, :name => 'first'}, {:id => 2, :name => 'second'}, {:id => 3, :name => 'third'}]
a.each {|h| o[h[:name]] = h[:id] }
puts o #{'third' => 3, 'second' => 2, 'first' => 1}
Related
I am using Ruby on Rails application. I want to combine 2 array of hashes with hash and to result in array of hashes.
Inputs:
first_array_of_hash = [{:name => "John", :age => 34, :mode => "nullable"},{:name => "Rose", :age => 30, :mode => "nullable"}]
second_hash = {:field_name => "", :field_age => nil, :field_nullable => false, :field_default => ""}
I want my result to be like below
result = [{:field_name => "John", :field_age => 34, :field_nullable => true, :field_default => ""},{:field_name => "Rose", :field_age => 30, :field_nullable => true, :field_default => ""}]
You can use a regular Array#map for this:
first_array_of_hash = [{:name => "John", :age => 34, :nullable => 'yes'},{:name => "Rose", :age => 30, :nullable => 'no'}]
second_hash = {:field_name => "", :field_age => nil, :field_nullable => false, :field_default => ""}
def transform(object)
{
field_name: object[:name],
field_age: object[:age],
field_nullable: object[:mode] == 'nullable'
}
end
result = first_array_of_hash.map do |object|
second_hash.merge(transform(object))
end
puts result
I'm having trouble with this api and can't seem to get over the hump. Using the HTTP gem (though I'm flexible and can use RestClient if that gets me an answer quicker!). Anyway, I'm having trouble posting an array. everything else is good, I just can't figure out this "itemsarray" in the printaura api found here in the addorder method: PrintAura API
I'm running this:
def self.submitorder
req = HTTP.post("https://api.printaura.com/api.php", :json => {
:key => APIKEY,
:hash => APIHASH,
:method => "addorder",
:businessname => "this is a secret too",
:businesscontact => "thats a secret",
:email => "my#email.com",
:your_order_id => "1",
:returnlabel => "FakeAddress",
:clientname => "ShippingName",
:address1 => "ShippingAddressLine1",
:address2 => "ShippingAddressLine2",
:city => "ShippingCity",
:state => "ShippingState",
:zip => "ShippingZip",
:country => "US",
:customerphone => "dontcallme",
:shipping_id => "1",
:itemsarray => {:item => [
:product_id => 423,
:brand_id => 33,
:color_id => 498,
:size_id => 4,
:front_print => 1389517,
:front_mockup => 1390615,
:quantity => 1
]}
})
puts JSON.parse(req)
end
And my output is this:
{"status"=>false, "error_code"=>19, "result"=>19, "message"=>"You cannot place an order without items, Please fill the items array with all the required information. Full API documentation can be found at https:/www.printaura.com/api/"}
Gosh, if someone could look at that and help me out I would forever appreciate it.
def self.submitorder
itemsarray = { :items => [ { :product_id => 423, :brand_id => 33, :color_id => 498, :size_id => 4, :quantity => 1, :front_print => 1389517,
:front_mockup => 1390617 } ] }
req = HTTP.post("https://api.printaura.com/api.php", :json => {
:key => APIKEY,
:hash => APIHASH,
:method => "addorder",
:businessname => "this is a secret too",
:businesscontact => "thats a secret",
:email => "my#email.com",
:your_order_id => "1",
:returnlabel => "FakeAddress",
:clientname => "ShippingName",
:address1 => "ShippingAddressLine1",
:address2 => "ShippingAddressLine2",
:city => "ShippingCity",
:state => "ShippingState",
:zip => "ShippingZip",
:country => "US",
:customerphone => "dontcallme",
:shipping_id => "1",
:items => Base64.encode64(itemsarray.to_json)}
)
puts JSON.parse(req)
I really hopes this helps somebody some years from now haha
To create a array in JSON you use an array in Ruby. Its that easy.
require 'json'
def self.submitorder
req = HTTP.post("https://api.printaura.com/api.php", :json => {
:key => APIKEY,
:hash => APIHASH,
:method => "addorder",
:businessname => "this is a secret too",
:businesscontact => "thats a secret",
:email => "my#email.com",
:your_order_id => "1",
:returnlabel => "FakeAddress",
:clientname => "ShippingName",
:address1 => "ShippingAddressLine1",
:address2 => "ShippingAddressLine2",
:city => "ShippingCity",
:state => "ShippingState",
:zip => "ShippingZip",
:country => "US",
:customerphone => "dontcallme",
:shipping_id => "1",
:items => [
{
:product_id => 423,
:brand_id => 33,
:color_id => 498,
:size_id => 4,
:front_print => 1389517,
:front_mockup => 1390615,
:quantity => 1
}
]
})
puts JSON.parse(req)
The API lists a items parameter which should contain an array of objects. It says nothing about itemsarray.
currently, I have a hash like this:
#lg = {
"Latin East Group" => [
{:id => 2, :name => "HONGKONG"},
{:id => 3, :name => "NINGBO, ZHEJIANG"},
{:id => 4, :name => "SINGAPORE"},
{:id => 5, :name => "LARCHMONT, NY"},
{:id => 6, :name => "CHICAGO, IL"},
{:id => 7, :name => "HAIPHONG"},
{:id => 8, :name => "DANANG"},
{:id => 9, :name => "HANOI"},
{:id => 10, :name => "MARSEILLE"},
{:id => 11, :name => "LONDON"},
{:id => 12, :name => "EDINBURGH"},
{:id => 13, :name => "AMSTERDAM"},
{:id => 14, :name => "HOCHIMINH"},
{:id => 15, :name => "SHANGHAI"}
],
"Latin West Group" => [],
"Others" => [
{:id => 16, :name => "Brazil" },
{:id => 17, :name => "Mexico" },
{:id => 18, :name => "Columbia"}
]
}
Now, I am using select2 with my form, and I wanna create a dropdown menu from that hash instance variable. I want the keys of the hash will be the optgroups, and the option values are gonna be the name sin the hash like Singapore, Brazil... Therefore, I am wondering what is the correct syntax for it. Currently, this is my code:
_form_body.haml:
%div.col-md-8
= f.grouped_collection_select :origin_locations, #lg, #lg.keys, #lg.values, {:selected => f.options[:origin_locations]}, {class: 'form-control select2-multiple origin_locations', :multiple => true}
pricing_histories_controller.rb:
def load_location_groups
#lg = {}
location_groups = LocationGroup.all.includes(:locations).each { |group|
#lg[group.name]= group.locations.map{|l| {id: l.id,name: l.name}}
}
# location_groups.each_with_index do |location_group, index|
arr = Location.where("id NOT IN (SELECT DISTINCT(location_id) FROM location_group_assignments)").pluck(:id,:name)
#location_groups = {}
#lg["Others"] = arr.map{ |e| {id: e.first, name: e.last}}
end
I will get the error:
ActionView::Template::Error (["Latin East Group", "Latin West Group",
"Others"] is not a symbol nor a string)
So, I am wondering what I am doing wrong here. Any suggestions would be appreciated. Thanks and have a nice day.
I have an array of Relation class on ruby on rails which I call using #relations
Example:
#relations[0] {id => 13, name => 'Giovanni', age => 50}
#relations[1] {id => 25, name => 'Astolf', age => 27}
#relations[2] {id => 5, name => 'Bob', age => 37}
I want to sort this array based on name. It'll as listed below:
#relations[0] {id => 25, name => 'Astolf', age => 27}
#relations[1] {id => 5, name => 'Bob', age => 37}
#relations[2] {id => 13, name => 'Giovanni', age => 50}
How can I do it?
very simple:
#relations = [{:id => 13, :name => 'Giovanni', :age => 50},
{:id => 25, :name => 'Astolf', :age => 27},
{:id => 5, :name => 'Bob', :age => 37}]
#relations.sort_by{|e| e[:name]}
# => [{:id=>25, :name=>"Astolf", :age=>27},
# {:id=>5, :name=>"Bob", :age=>37},
# {:id=>13, :name=>"Giovanni", :age=>50}]
I want to output an array of hashes with the name being unique to all hashes. How would I go about doing this using ruby?
This is my input:
input = [{:name => "Kutty", :score => 2, :some_key => 'value', ...},
{:name => "Kutty", :score => 4, :some_key => 'value', ...},
{:name => "Baba", :score => 5, :some_key => 'value', ...}]
I want the output to look like this:
output = [{:name => "Kutty", :score => 4, :some_key => 'value', ...},
{:name => "Baba", :score => 5, :some_key => 'value', ...}]
To just remove duplicates based on :name, simply try;
output = input.uniq { |x| x[:name] }
Demo here.
Edit: Since you added a sorting requirement in the comments, here's how to select the entry with the highest score for every name if you're using Rails, I see you already got an answer for "standard" Ruby above;
output = input.group_by { |x| x[:name] }
.map {|x,y|y.max_by {|x|x[:score]}}
A little explanation may be in order; the first line groups the entries by name so that each name gets its own array of entries. The second line goes through the groups, name by name, and maps each name group to the entry with the highest score.
Demo here.
input = [{:name => "Kutty", :score => 2, :some_key => 'value'},{:name => "Kutty", :score => 4, :some_key => 'value'},{:name => "Baba", :score => 5, :some_key => 'value'}]
p input.uniq { |e| e[:name] }
The above solution works for ruby > 1.9, for older versions of ruby you could use something along these lines:
input = [{:name => "Kutty", :score => 2, :some_key => 'value'},{:name => "Kutty", :score => 4, :some_key => 'value'},{:name => "Baba", :score => 5, :some_key => 'value'}]
unames = []
new_input = input.delete_if { |e|
if unames.include?(e[:name])
true
else
unames << e[:name]
false
end
}
p new_input
Try this solution..
input = [{:name => "Kutty", :score => 2, :some_key => 'value'},
{:name => "Kutty", :score => 4, :some_key => 'value'},
{:name => "Baba", :score => 5, :some_key => 'value'}]
a = []
output = []
input.collect do |i|
input.delete(i) if !a.include?(i[:name])
output << i if !a.include?(i[:name])
a << i[:name] if !a.include?(i[:name])
end
output = [{:some_key=>"value", :name=>"Kutty", :score=>2},
{:some_key=>"value", :name=>"Baba", :score=>5}]
UPDATED
output = {}
input.each do |e|
ref = output[e[:name]]
if ref && ref[:score] > e[:score]
#nothing
else
output[e[:name]] = e
end
end
check output:
puts output.values
input.uniq{|hash| hash[:name]}