我有这个数组[{:foo=>[{:bar=>[:baz]}]}, :foo, {:foo=>[{:bar=>[:bat]}]}, :bar]
如你所见,有符号和哈希。我想要做的是避免重复每个键或键内部值。
我想要的输出是:
[{:foo=>[{:bar=>[:baz, :bat]}]}, :bar]
正如你所看到的,没有重复foo或重复foo => bar。
我在这个问题上被困了好几个小时,我无法实现。有什么想法吗?
答案 0 :(得分:0)
以下会以某种方式运作:
input = [{:foo=>[{:bar=>[:baz]}]},
:foo,
{:foo=>[{:bar=>[:bat]}]},
:bar]
builder = ->(value, acc = {}) {
case value
when Hash
value.each_with_object(acc) do |(k, v), acc|
builder.(v, acc[k] ||= {})
end
when Array
value.each_with_object(acc) do |v, acc|
builder.(v, acc)
end
else acc[value] ||= {}
end
}
上面已经产生了或多或少可接受的结果:
puts (built = builder.(input)).inspect
#⇒ {:foo=>{:bar=>{:baz=>{}, :bat=>{}}}, :bar=>{}}
要准确地返回你想要的链接lambda(你无法事先告诉对象是否是一个叶子):
fixer = ->(acc) {
result = acc.all? { |*v| v.last.empty? } ? acc.keys :
acc.map { |k, v| v.empty? ? k : { k => fixer.(v) } }
result.size == 1 ? result.first : result
}
puts fixer.(built).inspect
#⇒ [{:foo=>{:bar=>[:baz, :bat]}}, :bar]
我相信您可以使用此代码来管理它以更好地满足您的需求。