Когда я смотрю на сценарий предоставления, я вижу следующее решение:
data = [{:mobile=>21, :web=>43},{:mobile=>23, :web=>543},{:mobile=>23, :web=>430},{:mobile=>34, :web=>13},{:mobile=>26, :web=>893}]
keys = [:mobile, :web]
result = keys.zip(data.map { |hash| hash.values_at(*keys) }.transpose).to_h
#=> {:mobile=>[21, 23, 23, 34, 26], :web=>[43, 543, 430, 13, 893]}
Сначала извлекаются значения ключей из каждого га sh, а затем транспонируется полученный массив. Это меняет [[21, 43], [23, 543], [23, 430], ...]
на [[21, 23, 23, ...], [43, 543, 430, ...]]
. Этот результат может быть возвращен к ключам и преобразован в ха sh.
. Чтобы избавиться от дубликатов, вы можете добавить .each(&:uniq!)
после вызова transpose
или сопоставить коллекции с набором .map(&:to_set)
(вам нужно require 'set'
), если вы не возражаете, что значения устанавливает вместо массивов.
result = keys.zip(data.map { |hash| hash.values_at(*keys) }.transpose.each(&:uniq!)).to_h
#=> {:mobile=>[21, 23, 34, 26], :web=>[43, 543, 430, 13, 893]}
require 'set'
result = keys.zip(data.map { |hash| hash.values_at(*keys) }.transpose.map(&:to_set)).to_h
#=> {:mobile=>#<Set: {21, 23, 34, 26}>, :web=>#<Set: {43, 543, 430, 13, 893}>}
Ссылки: