Merging Array objects into hash with an array - ruby-on-rails

I have an array of rooms: rooms_array = [room1...roomn] and each room is a hash with respective details. Each room hash has an offers hash.
room1 = {...., offers=> {...},...}
Now I have another array of offers hashes.
avg_array = [[{offer1},{offer2}],[{offer4},{offer3}],....]
Length of both the hashes is same, so first array of avg_array is for room1, second for room2 and so on...
My problem is how do I add each array of avg_array into corresponding offers hash of rooms_array.
My attempt:
_rooms.values.map do |room|
if room[:offers].count > 1
i=0
room[:offers] = rooms_hash[i]
i = i + 1
end
end

Looks like you might be able to do something using Array.zip
rooms.zip(avg_array).map do |room,avg|
room[:offers] = avg
room
end
If you want to append to an existing array:
rooms.zip(avg_array).map do |room,avg|
room[:offers] ||= []
room[:offers].concat avg
room
end
see:
What's the 'Ruby way' to iterate over two arrays at once

Related

Incrementing iteration through a hash in Ruby

What is the best way to incrementally iterate through a pair of hashes in Ruby? Should I convert them to arrays? Should I go an entirely different direction? I am working on a problem where the code is supposed to determine what to bake, and in what quantities, for a bakery given 2 inputs. The number of people to be fed, and their favorite food. They bake 3 things (keys in my_list) and each baked item feeds a set number of people (value in my_list).
def bakery_num(num_of_people, fav_food)
my_list = {"pie" => 8, "cake" => 6, "cookie" => 1}
bake_qty = {"pie_qty" => 0, "cake_qty" => 0, "cookie_qty" => 0}
if my_list.has_key?(fav_food) == false
raise ArgumentError.new("You can't make that food")
end
index = my_list.key_at(fav_food)
until num_of_people == 0
bake_qty[index] = (num_of_people / my_list[index])
num_of_people = num_of_people - bake_qty[index]
index += 1
end
return "You need to make #{pie_qty} pie(s), #{cake_qty} cake(s), and #{cookie_qty} cookie(s)."
end
The goal is to output a list for the bakery that will result in no uneaten food. When doing the math, the modulo would then be divided into the next food item.
Thanks for the help.
What is the best way to incrementally iterate through a pair of hashes in Ruby?
Since the keys of bake_qty conveniently have a '_qty' appended to them from their corresponding keys in my_list, you can use this to your advantage:
max_value = my_list[fav_food]
my_list.each do |key,value|
next if max_value < value
qty = bake_qty[key+'_qty']
...
end
You could use 'inject' method.
until num_of_people == 0
num_of_people = my_list.inject(num_of_people) do |t,(k,v)|
if num_of_people > 0
bake_qty["#{key}_qty"] += num_of_people/v
t - v
end
end
You can sort your hash at the beginning to ensure that your first food is the fav food

Efficient way to group this ruby array of objects

I have an array of instances of model Foo. Foo is an Ohm based data store. Each instance of Foo has an_id and integer attributes such as follows, likes. If there are two instances of Foo with the same an_id, I'd love to add the follows and likes attributes together. The solution I had was to create a hash where each key is an an_id of the array, and keep the state there. If the array is large enough, this is not efficient as I need each object back into an array. I'd love to group the array by Foo#an_id and merge/add the counter attributes together and pop that back into the array. Is something like this currently supported?
group_by, sum
As a start, something like this:
grouped_hash = your_array.group_by(&:an_id)
sums_by_id = {}
grouped_hash.each do |id,values|
sums_by_id[id] = {}
# you could also just iterate over values once and += :follows and :likes
sums_by_id[id][:follows] = values.sum(&:follows)
sums_by_id[id][:likes] = values.sum(&:likes)
end
Example output:
sums_by_id => {1 => {:follows => 2, :likes => 4}, 2 => ...
Additionally, take a look at:
inject
(5..10).inject {|sum, n| sum + n } # 45
You can use inject to get a sum of values:
array = *array of Foo*
total = array.inject { |sum, x| sum + x.likes }

Split an Array of arrays into 2 separate arrays in Ruby

I have a hash with some key value pairs as below:
#level2 = #l2.inject(Hash.new(0)) { |hash,element|
hash[element] +=1
hash }
I perform some sorting on the hash based on the keys.
#level2 = #level2.sort_by { |x, _| x }.reverse
Now I assume that the sort_by gives me an Array of Arrays. I want to split this into 2 arrays such that my first array should contain all keys and second array should contain all values.
The hash#keys and hash#values are not accessible after sorting the hash. So that does not work in this case.
Regardless of how you make the hash it will will have a Hash#keys method and a Hash#values. They both return arrays that are just what you seem to want.
keys_array = #level2.keys
values_array = #level2.values
You could iterate over the array of arrays and add each element to a new array. This would keep the order of the elements.
keys_array = []
values_array = []
#level2.each do |key, value|
keys_array << key
values_array << value
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

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