Czy istnieje łatwy lub elegancki sposób łączenia dwóch skrótów bez nadpisywania zduplikowanych kluczy?
Oznacza to, że jeśli klucz jest obecny w oryginalnym skrócie, nie chcę zmieniać jego wartości.
Czy istnieje łatwy lub elegancki sposób łączenia dwóch skrótów bez nadpisywania zduplikowanych kluczy?
Oznacza to, że jeśli klucz jest obecny w oryginalnym skrócie, nie chcę zmieniać jego wartości.
Odpowiedzi:
Jeśli masz dwa hashe, optionsi defaults, i chcesz połączyć defaultssię optionsbez nadpisywania istniejących kluczy, co naprawdę chcesz robić jest odwrotna: scalanie optionsw defaults:
options = defaults.merge(options)
Lub, jeśli używasz Railsów, możesz:
options.reverse_merge!(defaults)
reverse_merge!powodu problemów z bezpieczeństwem w szynach 5.1
Jeśli problem polega na tym, że oryginalny hash i drugi mogą mieć zduplikowane klucze i nie chcesz nadpisywać w żadnym kierunku, być może będziesz musiał przejść do prostego ręcznego scalania z pewnego rodzaju sprawdzaniem i obsługą kolizji:
hash2.each_key do |key|
if ( hash1.has_key?(key) )
hash1[ "hash2-originated-#{key}" ] = hash2[key]
else
hash1[key]=hash2[key]
end
end
Oczywiście jest to bardzo elementarne i zakłada, że hash1 nie ma żadnych kluczy zwanych „hash2-originated-cokolwiek” - może być lepiej, jeśli dodasz numer do klawisza, aby stał się kluczem1, kluczem2 i tak dalej, dopóki nie naciśniesz taki, który nie jest jeszcze w hash1. Poza tym nie robiłem żadnego rubinu przez kilka miesięcy, więc prawdopodobnie nie jest to poprawne składniowo, ale powinieneś być w stanie zrozumieć sedno.
Alternatywnie ponownie zdefiniuj wartość klucza jako tablicę, tak aby hash1 [klucz] zwracał oryginalną wartość z hash1 i wartość z hash2. Zależy od tego, jaki naprawdę ma być wynik.
Tutaj możesz połączyć swoje 2 hash przez 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 }
Jeśli chcesz scalić dwa skróty optionsi defaultsnie nadpisywać docelowego skrótu, możesz sprawdzić, selectczy klucz jest już obecny w docelowym skrócie. Oto czyste rozwiązanie Ruby bez 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}
Lub jeśli klucz jest obecny, ale zawiera nili chcesz go nadpisać:
options.merge!(defaults.select{ |k,_| options[k].nil? })