重复哈希键唯一对

Duplicate Hash Key unique Pair

我有一个数据对:

[{:mobile=>21, :web=>43},{:mobile=>23, :web=>543},{:mobile=>23, :web=>430},{:mobile=>34, :web=>13},{:mobile=>26, :web=>893}]

我怎样才能把它变成:

[{mobile: [21, 23, 34, 26]}, {web: [43, 543, 430, 13, 893]}

当我查看提供方案时,我看到以下解决方案:

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]}

这首先从每个散列中提取键的值,然后转置结果数组。这会将 [[21, 43], [23, 543], [23, 430], ...] 更改为 [[21, 23, 23, ...], [43, 543, 430, ...]]。这个结果可以压缩回密钥并转换成散列。

要删除重复项,您可以在 transpose 调用之后添加 .each(&:uniq!),或者将集合映射到集合 .map(&:to_set)(您需要 require 'set')如果你不介意值是 sets 而不是数组。

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}>}

参考文献: