Ruby: разделите один хэш на два на основе желаемых клавиш
Я надеюсь, что у этого вопроса будет очень простой ответ. Я могу придумать, как сделать это с скучным, раздражающим циклом, но я надеюсь, что там будет более элегантное решение.
Если у меня есть следующие две переменные:
hash = {:a => 1, :b => 2, :c => 3, :d => 4}
keyset = [:a, :c]
Как я могу получить следующие два хэша самым простым способом?
hash1 = {:a => 1, :c => 3}
hash2 = {:b => 3, :d => 4}
Если пример не делает мою цель ясной, в сущности, я хочу, чтобы гибрид между #delete
и #delete_if
- #delete
возвращал удаленное значение, тогда как #delete_if
позволяет мне удалять навалом, Я бы предпочел, чтобы удалить большой объем и вернуть удаленные значения - или что-то подобное.
Спасибо!
Ответы
Ответ 1
Попробуйте активную поддержку с Hash#slice
и/или Hash#except
. Существуют также методы взлома:
$ irb
>> require 'active_support/core_ext'
=> true
>> hash = {:a => 1, :b => 2, :c => 3, :d => 4}
=> {:a=>1, :d=>4, :b=>2, :c=>3}
>> keyset = [:a, :c]
=> [:a, :c]
>> remainders = hash.slice!(*keyset)
=> {:d=>4, :b=>2}
>> remainders
=> {:d=>4, :b=>2}
>> hash
=> {:a=>1, :c=>3}
Ответ 2
new_hash = {}
keyset.each {|i| new_hash[i] = hash.delete(i)}
Это, казалось, сделало это для меня, не требуя дополнительных требований
Ответ 3
hash = { a: 1, b: 2, c: 3, d: 4 }
keyset = [:a, :c]
left, right = hash.partition {|k,v| keyset.include? k }
Это оставляет влево и вправо как массивы массивов; вернитесь в хэш:
left = Hash[left]
right = Hash[right]
puts "left=#{left.inspect}"
puts "right=#{right.inspect}"
Ответ 4
С Rails/Active Support вы можете использовать метод extract!
:
hash = {:a => 1, :b => 2, :c => 3, :d => 4}
keyset = [:a, :c]
hash2 = hash.extract! *keyset
>> {:a=>1, :c=>3}
hash
>> {:b=>2, :d=>4}
Ответ 5
Если вы не возражаете против внешних зависимостей, вы можете использовать https://github.com/renra/split-off-ruby Тогда вы можете сделать:
hash2 = hash.split_off!(:b, :d)
hash все равно будет содержать исходные значения для ключей: a и: c. Вышеуказанные методы достаточно хороши, но иногда лучше выражать свое намерение с правильным именем метода, я считаю.