ฉันไปมากเกินไปและเกิดขึ้นกับสิ่งต่อไปนี้ แรงจูงใจของฉันที่อยู่เบื้องหลังสิ่งนี้คือการผนวกคีย์แฮชเพื่อหลีกเลี่ยงความขัดแย้งของขอบเขตเมื่อรวมเข้าด้วยกัน / แฮชที่แบนราบ
ตัวอย่าง
ขยายคลาสแฮช
เพิ่มเมธอด rekey ให้กับอินสแตนซ์ Hash
# Adds additional methods to Hash
class ::Hash
# Changes the keys on a hash
# Takes a block that passes the current key
# Whatever the block returns becomes the new key
# If a hash is returned for the key it will merge the current hash
# with the returned hash from the block. This allows for nested rekeying.
def rekey
self.each_with_object({}) do |(key, value), previous|
new_key = yield(key, value)
if new_key.is_a?(Hash)
previous.merge!(new_key)
else
previous[new_key] = value
end
end
end
end
ตัวอย่างการเตรียม
my_feelings_about_icecreams = {
vanilla: 'Delicious',
chocolate: 'Too Chocolatey',
strawberry: 'It Is Alright...'
}
my_feelings_about_icecreams.rekey { |key| "#{key}_icecream".to_sym }
# => {:vanilla_icecream=>"Delicious", :chocolate_icecream=>"Too Chocolatey", :strawberry_icecream=>"It Is Alright..."}
ตัดตัวอย่าง
{ _id: 1, ___something_: 'what?!' }.rekey do |key|
trimmed = key.to_s.tr('_', '')
trimmed.to_sym
end
# => {:id=>1, :something=>"what?!"}
แบนและผนวก "ขอบเขต"
หากคุณผ่านแฮชกลับไปที่ rekey มันจะรวมแฮที่อนุญาตให้คุณแผ่คอลเลกชัน สิ่งนี้ช่วยให้เราสามารถเพิ่มขอบเขตให้กับคีย์ของเราเมื่อทำการแฮชที่แบนราบเพื่อหลีกเลี่ยงการเขียนทับคีย์เมื่อทำการผสาน
people = {
bob: {
name: 'Bob',
toys: [
{ what: 'car', color: 'red' },
{ what: 'ball', color: 'blue' }
]
},
tom: {
name: 'Tom',
toys: [
{ what: 'house', color: 'blue; da ba dee da ba die' },
{ what: 'nerf gun', color: 'metallic' }
]
}
}
people.rekey do |person, person_info|
person_info.rekey do |key|
"#{person}_#{key}".to_sym
end
end
# =>
# {
# :bob_name=>"Bob",
# :bob_toys=>[
# {:what=>"car", :color=>"red"},
# {:what=>"ball", :color=>"blue"}
# ],
# :tom_name=>"Tom",
# :tom_toys=>[
# {:what=>"house", :color=>"blue; da ba dee da ba die"},
# {:what=>"nerf gun", :color=>"metallic"}
# ]
# }