У меня есть массив хэшей, и я хочу получить уникальные значения. Вызов Array.uniq не дает мне того, что я ожидаю.
a = [{:a => 1},{:a => 2}, {:a => 1}]
a.uniq # => [{:a => 1}, {:a => 2}, {:a => 1}]
Где я ожидал:
[{:a => 1}, {:a => 2}]
При поиске в сети я не придумал решение, которым я был доволен. Людям рекомендуется переопределять Hash.eql? и Hash.hash, так как это запрос Array.uniq.
Изменить: Где я столкнулся с этим в реальном мире, хеши были немного сложнее. Они были результатом разобранного JSON, который имел несколько полей, некоторые из которых были также значениями хэшей. У меня был массив этих результатов, которые я хотел отфильтровать уникальные значения.
Мне не нравится решение redefine Hash.eql? и Hash.hash, потому что мне нужно либо переопределить Hash глобально, либо переопределить его для каждой записи в моем массиве. Изменение определения Hash для каждой записи было бы громоздким, тем более, что внутри каждой записи могут быть вложенные хэши.
Изменение Hash во всем мире имеет некоторый потенциал, особенно если это было сделано временно. Я хотел бы создать еще один класс или вспомогательную функцию, которая завершает сохранение старых определений и восстанавливает их, но я думаю, что это добавляет больше сложности, чем это действительно необходимо.
Использование inject кажется хорошей альтернативой переопределению Hash.