我有一个哈希,由.group_by
方法创建,字符串作为键,AR对象作为值。我想摆脱带有重复字段的 AR 对象(其他字段可能相同,也可能不同)。
为了澄清这个问题,我创建了这个片段:
require 'ostruct'
def os_new(fid); OpenStruct.new(fid: fid, rand: rand(100)); end
a = [os_new(1), os_new(2), os_new(3)]
b = [os_new(3), os_new(3), os_new(2)]
c = [os_new(5), os_new(5), os_new(5), os_new(5)]
grouped_hash = { a: a, b: b, c: c}
grouped_hash
是:
# {:a=>[#<OpenStruct fid=1, rand=7>, #<OpenStruct fid=2, rand=50>, #<OpenStruct fid=3, rand=13>],
# :b=>[#<OpenStruct fid=3, rand=51>, #<OpenStruct fid=3, rand=58>, #<OpenStruct fid=2, rand=88>],
# :c=>[#<OpenStruct fid=5, rand=40>, #<OpenStruct fid=5, rand=8>, #<OpenStruct fid=5, rand=45>, #<OpenStruct fid=5, rand=72>]}
现在,结果我想要一个具有每个键唯一fid
的哈希:
# {:a=>[#<OpenStruct fid=1, rand=7>, #<OpenStruct fid=2, rand=50>, #<OpenStruct fid=3, rand=13>],
# :b=>[#<OpenStruct fid=3, rand=51>, #<OpenStruct fid=2, rand=88>],
# :c=>[#<OpenStruct fid=5, rand=40>]}
我的解决方案需要几个操作,看起来很丑陋。
grouped_hash.each_value do |value|
fids = []
value.delete_if do |object|
if fids.include? object.fid
true
else
fids << object.fid
false
end
end
end
我正在寻找最优雅(可能是 1 行)和最有效的方式(没有哈希重新创建)。
grouped_hash.each_value(&:uniq)
根据AR对象,Rails故意将相等性检查委托给身份列。如果您想知道两个 AR 对象包含相同的值,请比较在两个对象上调用 #attributes 的结果。
不完全是一行(尽管您也可以用一行写):
grouped_hash.inject({}) do |hash, element|
hash[element.first] = element.last.uniq(&:fid)
hash
end
通过结合 Tensho 和 katafrakt(谢谢你们)的答案,我做了这个:
grouped_hash.each_value { |v| v.uniq!(&:fid) }