如何从数组创建散列
How to create hash from 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]]
我需要做:
{ 'Friday' => [ ["42", 8], ["34", 8], ["41", 78], ["35", 7], [ "40", 7], ["36", 6], [ "39", 7], ["37", 56], [ "38", 6] ] }
与 "Monday"
相同。有人可以解释一下吗?
这就是我从 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}}}
然后我把它变成数组并排序:
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_array = hash_array.sort_by &:first
我有一个快速的解决方案给你。这可能不是最佳的,但这里是:
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]
这将return您需要的结果。但是在这样做的时候我发现了一个限制,即代码行:
s = sorted_array.select{|x| x[0] == 'Friday'}.each{|a| a.shift}
只是 运行 一次,如果您连续第二次 运行 它将 return 一个空白数组。因此,如果您使用它,请注意这一点。希望这有帮助。
这是 Array#reduce
的标准任务。
sorted_array.reduce({}) { |memo, e|
(memo[e.first] ||= []) << e[1..-1]
memo
}
在这里,我们使用第一个元素作为键,用每个数组元素的其余部分来实现散列。
UPD其实,你不需要重新组织你的哈希,一切都可以一步完成:
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
}
您可以直接对您的数据尝试这样的操作:
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}]}
如果需要,您可以通过对哈希数组使用 Array#uniq 来进一步改进结果。
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]]}
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] ] }
两个买一个:
#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 }
Ruby 魔法:
p sorted_array.group_by(&:shift) #=> {"Friday"=>[["42", 8], ["34", 8], ["41", 78], ["35", 7] ...
解释:shift
获取数组的第一个值,同时从数组中删除它,所以group_by函数产生的正是你要找的。
这是我的数组:
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]]
我需要做:
{ 'Friday' => [ ["42", 8], ["34", 8], ["41", 78], ["35", 7], [ "40", 7], ["36", 6], [ "39", 7], ["37", 56], [ "38", 6] ] }
与 "Monday"
相同。有人可以解释一下吗?
这就是我从 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}}}
然后我把它变成数组并排序:
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_array = hash_array.sort_by &:first
我有一个快速的解决方案给你。这可能不是最佳的,但这里是:
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]
这将return您需要的结果。但是在这样做的时候我发现了一个限制,即代码行:
s = sorted_array.select{|x| x[0] == 'Friday'}.each{|a| a.shift}
只是 运行 一次,如果您连续第二次 运行 它将 return 一个空白数组。因此,如果您使用它,请注意这一点。希望这有帮助。
这是 Array#reduce
的标准任务。
sorted_array.reduce({}) { |memo, e|
(memo[e.first] ||= []) << e[1..-1]
memo
}
在这里,我们使用第一个元素作为键,用每个数组元素的其余部分来实现散列。
UPD其实,你不需要重新组织你的哈希,一切都可以一步完成:
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
}
您可以直接对您的数据尝试这样的操作:
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}]}
如果需要,您可以通过对哈希数组使用 Array#uniq 来进一步改进结果。
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]]}
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] ] }
两个买一个:
#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 }
Ruby 魔法:
p sorted_array.group_by(&:shift) #=> {"Friday"=>[["42", 8], ["34", 8], ["41", 78], ["35", 7] ...
解释:shift
获取数组的第一个值,同时从数组中删除它,所以group_by函数产生的正是你要找的。