Reputation: 5304
Here is my array:
sorted_array = [["Friday", "42", 8], ["Friday", "34", 8], ["Friday", "41", 78], ["Friday", "35", 7], ["Friday", "40", 7], ["Friday", "36", 6], ["Friday", "39", 7], ["Friday", "37", 56], ["Friday", "38", 6], ["Monday", "38", 3], ["Monday", "39", 5], ["Monday", "37", 54], ["Monday", "40", 6], ["Monday", "36", 6], ["Monday", "41", 7], ["Monday", "35", 7], ["Monday", "42", 7], ["Monday", "34", 8]]
I need to make:
{ 'Friday' => [ ["42", 8], ["34", 8], ["41", 78], ["35", 7], [ "40", 7], ["36", 6], [ "39", 7], ["37", 56], [ "38", 6] ] }
The same with "Monday"
.Can someone shed a light on this?
This is how I get the data from POST:
{"0"=>{"Monday"=>{"34"=>8}, "Friday"=>{"34"=>8}}, "1"=>{"Monday"=>{"35"=>7}, "Friday"=>{"35"=>7}}, "2"=>{"Monday"=>{"36"=>6}, "Friday"=>{"36"=>6}}, "3"=>{"Monday"=>{"37"=>54}, "Friday"=>{"37"=>56}}, "4"=>{"Monday"=>{"38"=>3}, "Friday"=>{"38"=>6}}, "5"=>{"Monday"=>{"39"=>5}, "Friday"=>{"39"=>7}}, "6"=>{"Monday"=>{"40"=>6}, "Friday"=>{"40"=>7}}, "7"=>{"Monday"=>{"41"=>7}, "Friday"=>{"41"=>78}}, "8"=>{"Monday"=>{"42"=>7}, "Friday"=>{"42"=>8}}}
Then I turn it into array and sorted:
hash_array = []
specific_ranges.each do |key, value|
value.each do |day, scores|
scores.each do |a_score, amount|
hash_array.push [day, a_score, amount]
end
end
end
Sorted:
sorted_array = hash_array.sort_by &:first
Upvotes: 1
Views: 101
Reputation: 13901
Ruby MAGIC:
p sorted_array.group_by(&:shift) #=> {"Friday"=>[["42", 8], ["34", 8], ["41", 78], ["35", 7] ...
Explanation: shift
gets the first value of the array and at the same time removes it from the array, so the group_by function produce exactly what you are looking for.
Upvotes: 5
Reputation: 110675
Two for the price of one:
#1
arr.each_with_object({}) { |a,h| h.update(a.shift=>[a]) { |_,o,n| o+n } }
#2
h = arr.group_by(&:first)
h.each { |k,v| h[k] = v.transpose[1..-1].transpose }
Upvotes: 0
Reputation: 168081
h = sorted_array.group_by(&:first).each_value{|a| a.each(&:shift)}
h.select{|k, _| k == "Friday"}
#=> { 'Friday' => [ ["42", 8], ["34", 8], ["41", 78], ["35", 7], [ "40", 7], ["36", 6], [ "39", 7], ["37", 56], [ "38", 6] ] }
Upvotes: 1
Reputation: 121000
This is a standard task for Array#reduce
.
sorted_array.reduce({}) { |memo, e|
(memo[e.first] ||= []) << e[1..-1]
memo
}
Here we fulfill the hash with the rest of every array element, using first elements as keys.
UPD Actually, you don’t need to reorganize your hash, everything might be done within one step:
h = {"0"=>{"Monday"=>{"34"=>8}, "Friday"=>{"34"=>8}}, "1"=>{"Monday"=>{"35"=>7}, "Friday"=>{"35"=>7}}, "2"=>{"Monday"=>{"36"=>6}, "Friday"=>{"36"=>6}}, "3"=>{"Monday"=>{"37"=>54}, "Friday"=>{"37"=>56}}, "4"=>{"Monday"=>{"38"=>3}, "Friday"=>{"38"=>6}}, "5"=>{"Monday"=>{"39"=>5}, "Friday"=>{"39"=>7}}, "6"=>{"Monday"=>{"40"=>6}, "Friday"=>{"40"=>7}}, "7"=>{"Monday"=>{"41"=>7}, "Friday"=>{"41"=>78}}, "8"=>{"Monday"=>{"42"=>7}, "Friday"=>{"42"=>8}}}
h.reduce({}) { |memo, k|
k.last.each { |k,v| (memo[k] ||= []) << v.to_a.flatten }
memo
}
Upvotes: 0
Reputation: 16506
you can try something like this directly to your data:
data = {"0"=>{"Monday"=>{"34"=>8}, "Friday"=>{"34"=>8}}, "1"=>{"Monday"=>{"35"=>7}, "Friday"=>{"35"=>7}}, "2"=>{"Monday"=>{"36"=>6}, "Friday"=>{"36"=>6}}, "3"=>{"Monday"=>{"37"=>54}, "Friday"=>{"37"=>56}}, "4"=>{"Monday"=>{"38"=>3}, "Friday"=>{"38"=>6}}, "5"=>{"Monday"=>{"39"=>5}, "Friday"=>{"39"=>7}}, "6"=>{"Monday"=>{"40"=>6}, "Friday"=>{"40"=>7}}, "7"=>{"Monday"=>{"41"=>7}, "Friday"=>{"41"=>78}}, "8"=>{"Monday"=>{"42"=>7}, "Friday"=>{"42"=>8}}}
a ||= Hash.new { |h, k| h[k] = [] }
data.each{ |d|
d[1].keys.each { |key|
a[key] << d[1][key]
}
}
a
# => {"Monday"=>[{"34"=>8}, {"35"=>7}, {"36"=>6}, {"37"=>54}, {"38"=>3}, {"39"=>5}, {"40"=>6}, {"41"=>7}, {"42"=>7}], "Friday"=>[{"34"=>8}, {"35"=>7}, {"36"=>6}, {"37"=>56}, {"38"=>6}, {"39"=>7}, {"40"=>7}, {"41"=>78}, {"42"=>8}]}
You can improve the result further by using Array#uniq for array of hashes if required.
Upvotes: 2
Reputation: 29114
sorted_array.group_by(&:first).map { |k, v| [k, v.map { |a| a[1..-1] }] }.to_h
# {"Friday"=>[["42", 8], ["34", 8], ["41", 78], ["35", 7], ["40", 7], ["36", 6], ["39", 7], ["37", 56], ["38", 6]],
# "Monday"=>[["38", 3], ["39", 5], ["37", 54], ["40", 6], ["36", 6], ["41", 7], ["35", 7], ["42", 7], ["34", 8]]}
Upvotes: 1
Reputation: 6398
I have a quick solution for you. This may not be the optimal but here it is:
sorted_array = [["Friday", "42", 8], ["Friday", "34", 8], ["Friday", "41", 78], ["Friday", "35", 7], ["Friday", "40", 7], ["Friday", "36", 6], ["Friday", "39", 7], ["Friday", "37", 56], ["Friday", "38", 6], ["Monday", "38", 3], ["Monday", "39", 5], ["Monday", "37", 54], ["Monday", "40", 6], ["Monday", "36", 6], ["Monday", "41", 7], ["Monday", "35", 7], ["Monday", "42", 7], ["Monday", "34", 8]]
s = sorted_array.select{|x| x[0] == 'Friday'}.each{|a| a.shift}
Hash['Friday', s]
This will return the result as you require. But while doing it I found a limitation that the line of code:
s = sorted_array.select{|x| x[0] == 'Friday'}.each{|a| a.shift}
is running just a single time and it will return a blank array if you run it the second time consecutively. So if you use this please take care of that. Hope this helps.
Upvotes: 0