The below code is completely working :
a = [{:a=>1},{:a=>10},{:b=>8},{:c=>7},{:c=>2}]
merged_hash = a.each_with_object({}) do |item,hsh|
k,v = item.shift
hsh.has_key?(k) ? hsh[k] = [v] << hsh[k] : hsh[k] = v
end
merged_hash.map { |k,v| { k => v } }
=> [{:a=>[10, 1]}, {:b=>8}, {:c=>[2, 7]}]
But, Is it a expressive code or some tweak can still be applied on this
?
On Tue, Mar 11, 2014 at 9:47 AM, Arup R. [email protected]
wrote:
But, Is it a expressive code or some tweak can still be applied on this
?
Although it’s not exactly the same solution (single elements end up in
arrays too), I propose this:
2.0.0p195 :005 > a = [{:a=>1},{:a=>10},{:b=>8},{:c=>7},{:c=>2}]
=> [{:a=>1}, {:a=>10}, {:b=>8}, {:c=>7}, {:c=>2}]
2.0.0p195 :006 > merged_hash = Hash.new {|h,k| h[k] = []}
=> {}
2.0.0p195 :007 > a.each {|h| h.each {|k,v| merged_hash[k] << v}}
=> [{:a=>1}, {:a=>10}, {:b=>8}, {:c=>7}, {:c=>2}]
2.0.0p195 :008 > merged_hash
=> {:a=>[1, 10], :b=>[8], :c=>[7, 2]}
It might give you some ideas.
Jesus.
On 03/11/2014 01:47 AM, Arup R. wrote:
But, Is it a expressive code or some tweak can still be applied on this
?
This is slightly different than your example (so not a “true
refactoring” I guess). I don’t modify the original array and all
“values” in the result are arrays, which seems more consistent:
This is all just to avoid assigning k and v when iterating over values
a =
[{:a=>1},{:a=>10},{:b=>8},{:c=>7},{:c=>2}].map(&:to_a).map(&:flatten)
merged = Hash.new { |h, k| h[k] = { k => [] } }
a.each do |k, v|
merged[k][k] << v
end
merged.values
=> [{:a=>[1, 10]}, {:b=>[8]}, {:c=>[7, 2]}]
No guarantees this code will be more efficient or better in any way.
-Justin
On Tue, Mar 11, 2014 at 9:47 AM, Arup R. [email protected]
wrote:
The below code is completely working :
a = [{:a=>1},{:a=>10},{:b=>8},{:c=>7},{:c=>2}]
merged_hash = a.each_with_object({}) do |item,hsh|
k,v = item.shift
hsh.has_key?(k) ? hsh[k] = [v] << hsh[k] : hsh[k] = v
end
merged_hash.map { |k,v| { k => v } }
=> [{:a=>[10, 1]}, {:b=>8}, {:c=>[2, 7]}]
Why do you want to have an Array with Hashes as result? Since you are
grouping by key a single Hash seems like a much better choice.
irb(main):001:0> a = [{:a=>1},{:a=>10},{:b=>8},{:c=>7},{:c=>2}]
=> [{:a=>1}, {:a=>10}, {:b=>8}, {:c=>7}, {:c=>2}]
irb(main):002:0> merged = Hash.new {|h,k| h[k]=[]}
=> {}
irb(main):003:0> a.each {|h| h.each {|k,v| merged[k] << v}}
=> [{:a=>1}, {:a=>10}, {:b=>8}, {:c=>7}, {:c=>2}]
irb(main):004:0> merged
=> {:a=>[1, 10], :b=>[8], :c=>[7, 2]}
Kind regards
robert
One more refactoring :
All is working.
hash = {
“properties”=>{
“one”=>“extra”,
“headers”=>{
“type”=>“object”,
“type1”=>“object2”
},
“entity”=>{
“type”=>“entype”
},
},
“sec_prop”=>“hmmm”
}
def fetch_keys(h)
h.flat_map do |k,v|
if v.is_a?(Hash)
fetch_keys(v).map do |keys|
[k] + Array(keys)
end
else
k
end
end
end
fetch_keys(hash)
=> [[“properties”, “one”],
[“properties”, “headers”, “type”],
[“properties”, “headers”, “type1”],
[“properties”, “entity”, “type”],
“sec_prop”]
Just thinking if the below can be done in any other way ?
fetch_keys(v).map do |keys|
[k] + Array(keys)
end
On Wed, Mar 12, 2014 at 11:32 AM, Arup R. [email protected]
wrote:
One more refactoring :
[…]
Just thinking if the below can be done in any other way ?
You keep changing structure and contents of your data structure. It’s
impossible to determine what your goal is so it’s hard to come up with
suggestions. I suggest you explain what you are trying to do.
Cheers
robert
Anyhow I reached to this one :
a = [{:a=>1},{:a=>10},{:b=>8},{:c=>7},{:c=>2}]
merged_hash = a.each_with_object({}) do |item,hsh|
k,v = item.shift
(hsh[k] ||= []) << v
end
p merged_hash.map { |k,v| { k => v } }
=> [{:a=>[10, 1]}, {:b=>8}, {:c=>[2, 7]}]
Robert K. wrote in post #1139595:
On Wed, Mar 12, 2014 at 11:32 AM, Arup R. [email protected]
wrote:
robert
Sorry this totally different question. As related to refactoring
I put
here. Would you want me to post it separately ?
Sorry for creating the confusions.
On Wed, Mar 12, 2014 at 1:26 PM, Arup R. [email protected]
wrote:
Robert K. wrote in post #1139595:
Sorry this totally different question. As related to refactoring
I put
here. Would you want me to post it separately ?
Yes, that’s good practice. By keeping things separate you make it
easier for people to follow, reply and find solutions later.
Sorry for creating the confusions.
No problem.
Cheers
robert