如何深度合并由数组和散列组成的两个多根树结构

我有一个由Hash es和Array的嵌套结构,我们可以称之为多根nth-ary Tree。

我代表这个结构

这是一个例子:

 [:o, { a: :b, c: [:d, :e, { f: { h: :i, l: [:m, :n] } }] }] 

代表可以用这个模式表示:

 oac / /|\ bdef /\ hl / / \ imn 

我想深深地将它与另一个类似的结构合并。 这是一个例子:

 [:z, { o: :s, c: [:f, { d: :w }] }] zoc | / \ sfd \ w 

生成的树应该是这样的:

 [:z, { a: :b, c: [:e, { f: { h: :i, l: [:m, :n] }, d: :w }], o: :s }] zaco | /|\ | befds /| \ hlw | |\ imn 

我怎样才能做到这一点?

我从这开始,但我被击中了:

 def deep_merge(a, b) case a when Hash case b when Hash merge_hashes(a, b) when Array merge_array_hash(b, a) else [b, a] end when Array case b when Array merge_arrays(a, b) when Hash merge_array_hash(a, b) else [b] + a end else case b when Hash [a, b] when Array [a] + b else a == b ? a : [a, b] end end end # EXAMPLES: # merge_array_hash([:a, :b], { f: :w }) # => [:a, :b, { f: :w }] # merge_array_hash([:a, :b, { c: :d }], { f: :w }) # => [:a, :b, { c: :d, f: :w }] def merge_array_hash(a, b) if a.last.is_a? Hash a[0...-1] + [merge_hashes(a.last, b)] else a + [b] end end # EXAMPLES: # merge_hashes({ a: :b }, { c: :d }) # => { a: :b, c: :d } # merge_hashes({ a: :b }, { d: e, a: :f }) # => { a: [:b, :f], d: :e } def merge_hashes(a, b) a.deep_merge(b) do |_, this_val, other_val| deep_merge(this_val, other_val) end end # EXAMPLES: # merge_arrays([:a, :b], [:c]) # => [:a, :b, :c] # merge_arrays([:a, :b { c: :d }], [:f, { c: :e }]) # => [:a, :b, :f, { c: [:d, :e] }] # merge_arrays([:a, :b { c: :d }], [:f, { c: :e }]) # => [:a, :b, :f, { c: [:d, :e] }] def merge_arrays(a, b) keys = merge_array_keys(a, b) hashes = merge_hashes(a.last.is_a?(Hash) ? a.last : {}, b.last.is_a?(Hash) ? a.last : {}) hashes.empty? keys : (keys + [hashes]) end # EXAMPLES: # merge_array_keys([:a, :b], [:f]) # => [:a, :b, :f] # merge_array_keys([:a, :b { c: :d }], [:f, { c: :e }]) # => [:a, :b, :f] def merge_array_keys(a, b) a.reject { |e| e.is_a?(Hash) } + b.reject { |e| e.is_a?(Hash) } end 

正如你所看到的,我的解决方案有点过于复杂,我认为有一种更聪明的方式,但我找不到它。 有任何想法吗?

注意:关键顺序不符合要求

注意:如果存在包含哈希的数组,则哈希必须是数组的最后一项

NB:我对表演不感兴趣,大树也可能很慢

注意:如果你有更好的想法以更聪明的方式表示这个结构,对我来说没问题!