Если вы используете activesupport (часть рельсов), вы можете воспользоваться 2 дополнительными методами для Hash
:
Hash#slice
принимает нужные ключи в качестве отдельных аргументов (не массив ключей) и возвращает новый хэш только с теми ключами, которые вы запрашивали.
Hash#except
принимает те же аргументы, что и slice
, но возвращает новый хеш с ключами, которых не было в аргументах.
Первая загрузка активной поддержки:
require 'active_support/core_ext'
Объединять только записи из j
, ключи которых уже находятся в h
(т.е. изменять, но не добавлять и не удалять записи в h
):
h.merge(j.slice(*h.keys))
* * Пример тысяча двадцать-один: * * 1 022
ignore_new = ->(h, j) { h.merge(j.slice(* h.keys)) }
ignore_new.({a: 1, b: 2, c: 3}, {b: 10, c: 11, d: 12})
# => {:a=>1, :b=>10, :c=>11}
Получить остатки от j
, которых не было в h
:
j.except(*h.keys)
Бонус:
Если вы хотите истинное пересечение, то есть вы хотите получить результат, в котором есть только ключи, общие для двух хешей, сделайте следующее:
h.merge(j).slice(* ( h.keys & j.keys ) )
Пример:
intersect = ->(h, j) { h.merge(j).slice(* (h.keys & j.keys) ) }
intersect.({a: 1, b: 2, c: 3}, {b: 10, c: 11, d: 12})
# => {:b=>10, :c=>11}
и остатки от h
, которых не было в j
:
h.except(*j.keys)
Возможно, вы также захотите использовать HashWithIndifferentAccess
activesupport, если хотите, чтобы доступ к строке и символьному ключу считался эквивалентным.
Обратите внимание, что ни один из приведенных выше примеров не изменяет исходные хэши; вместо этого возвращаются новые хэши.