Có một cách dễ dàng hoặc thanh lịch để hợp nhất hai băm mà không ghi đè các khóa trùng lặp?
Đó là, nếu khóa có mặt trong hàm băm ban đầu, tôi không muốn thay đổi giá trị của nó.
Có một cách dễ dàng hoặc thanh lịch để hợp nhất hai băm mà không ghi đè các khóa trùng lặp?
Đó là, nếu khóa có mặt trong hàm băm ban đầu, tôi không muốn thay đổi giá trị của nó.
Câu trả lời:
Nếu bạn có hai giá trị băm options
và defaults
, và bạn muốn hợp nhất defaults
vào options
mà không ghi đè các khóa hiện có, điều bạn thực sự muốn làm là ngược lại: hợp nhất options
vào defaults
:
options = defaults.merge(options)
Hoặc, nếu bạn đang sử dụng Rails, bạn có thể làm:
options.reverse_merge!(defaults)
reverse_merge!
vì các vấn đề an ninh trong đường ray 5.1
Nếu vấn đề của bạn là hàm băm ban đầu và hàm thứ hai đều có khóa trùng lặp và bạn không muốn ghi đè theo một trong hai hướng, bạn có thể phải thực hiện hợp nhất thủ công đơn giản với một số loại kiểm tra và xử lý va chạm:
hash2.each_key do |key|
if ( hash1.has_key?(key) )
hash1[ "hash2-originated-#{key}" ] = hash2[key]
else
hash1[key]=hash2[key]
end
end
Rõ ràng, điều này rất thô sơ và giả sử rằng hash1 không có bất kỳ khóa nào được gọi là "hash2-originated-anything" - bạn có thể tốt hơn là chỉ cần thêm một số vào khóa để nó trở thành key1, key2 và cứ thế cho đến khi bạn nhấn vào một cái chưa có trong hash1. Ngoài ra, tôi đã không thực hiện bất kỳ viên ruby nào trong vài tháng nên có lẽ điều đó không chính xác về mặt cú pháp, nhưng bạn sẽ có thể có được ý chính.
Hoặc xác định lại giá trị của khóa dưới dạng một mảng để hash1 [key] trả về giá trị ban đầu từ hash1 và giá trị từ hash2. Phụ thuộc vào những gì bạn muốn kết quả của bạn thực sự.
Tại đây bạn có thể hợp nhất 2 hàm băm của mình bằng cách reverse_merge
order = {
id: 33987,
platform: 'web'
}
user = {
name: 'Jhon Doe',
email: 'jhon.doe@gmail.com'
}
newHash = oder.reverse_merge!(user)
render json: { data: newHash, status: 200 }
Nếu bạn muốn hợp nhất hai băm options
và defaults
không ghi đè băm đích, bạn có thể kiểm tra xem select
khóa đã có trong băm đích chưa. Đây là giải pháp Ruby thuần túy không có Rails:
options = { "a" => 100, "b" => 200 }
defaults = { "b" => 254, "c" => 300 }
options.merge!(defaults.select{ |k,_| not options.has_key? k })
# output
# => {"a"=>100, "b"=>200, "c"=>300}
Hoặc nếu khóa có mặt, nhưng chứa nil
và bạn muốn ghi đè lên nó:
options.merge!(defaults.select{ |k,_| options[k].nil? })