问题描述
有两个哈希数组
actual = [{id: 1,text: "A",type: "X",state: "enabled"},{id: 2,text: "B",state: "enabled"}]
expected = [{text: "A",state: "enabled"}]
我需要获取未包含在“预期”中的所有哈希的:id。比较必须使用三个键(文本,类型,状态)完成。在这种情况下
results = [{id: 2}]
此刻,我正在使用它,但是它很长,并且不能用于大型阵列。有更好的方法吗?
actuals = actuals.map{|a| a.slice(:text,:type,:state)}
expected = expected.map{|a| a.slice(:text,:state)}
not_expected = actuals - expected
results = actuals.select{|actual|
not_expected.find{|n|
n[:text] == actual[:text] &&
n[:type] == actual[:type] &&
n[:state] == actual[:state]
}.present?
}
解决方法
actual = [{id: 1,text: "A",type: "X",state: "enabled"},{id: 2,text: "B",state: "enabled"}]
expected = [{text: "A",state: "enabled"}]
comparable_expected = expected.map { |e| e.slice(:text,:type,:state) }
results = actual.select do |a|
not comparable_expected.include? a.slice(:text,:state)
end
resulting_ids = results.map(&:id)
,
exp = expected.first
#=> {text: "A",state: "enabled"}
actual.reject { |h| h == h.merge(exp) }.map { |h| h.slice(:id) }
#=> [{:id=>2}]
actual
中的散列如果与exp
合并时不受影响,则被拒绝,这意味着要合并的散列对于exp
中的所有键具有相同的值。然后,使用Hash#slice将h
中每个剩余的哈希actual
映射到{ id: h[:id] }
。
该方法的一个优点是,如果将exp
更改为具有不同键的哈希,则无需更改代码。