Ruby: разбить один хеш на два на основе нужных ключей - PullRequest
22 голосов
/ 10 июля 2009

Я надеюсь, что на этот вопрос очень простой ответ. Я могу придумать способы сделать это со скучными, раздражающими циклами, но я надеюсь, что есть более элегантное решение.

Если у меня есть следующие две переменные:

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 позволяет мне массово удалять , Я бы предпочел способ массового удаления с возвратом удаленных значений - или что-то эквивалентное.

Спасибо!

Ответы [ 5 ]

33 голосов
/ 10 июля 2009

Попробуйте активную поддержку с 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}
12 голосов
/ 09 марта 2013
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}"
12 голосов
/ 10 июля 2009
new_hash = {}
keyset.each {|i| new_hash[i] = hash.delete(i)}

Это, казалось, сделало это для меня без дополнительных требований

2 голосов
/ 07 июня 2016

С помощью 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}
0 голосов
/ 10 января 2014

Если вы не возражаете против внешних зависимостей, вы можете использовать https://github.com/renra/split-off-ruby Тогда вы можете сделать:

hash2 = hash.split_off!(:b, :d)

хеш будет по-прежнему содержать исходные значения для ключей: a и: c. Вышеуказанные методы достаточно хороши, но иногда лучше выразить свои намерения с правильным именем метода, я считаю.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...