2017-09-14 48 views
-1

我拥有这个数组[{:foo=>[{:bar=>[:baz]}]}, :foo, {:foo=>[{:bar=>[:bat]}]}, :bar] 正如您所看到的那样存在符号和哈希值。我试图做的是避免重复每个键或值内的键。 我所需的输出是:将哈希和符号数组转换为唯一

[{:foo=>[{:bar=>[:baz, :bat]}]}, :bar] 

正如你所看到的,有没有关键FOO或FOO =>栏的重复重复。

我一直坚持在这一个小时,我无法实现它。任何想法?

+0

通过散列值进行递归迭代将会_almost_做。事情就是如上所述的问题**没有解决方案**。想想'{foo:[:bar]},{foo:{bar:[:baz]}}'。 – mudasobwa

+0

是的,这正是我发生的事情。我几乎得到它,但从来没有出现最终的解决方案。 – Ruffeng

+0

可能是我的问题是在构建这个特定数组的时刻,因为我来自一个数组(“foo.bar.baz,foo,foo.bar.bat,bar”) – Ruffeng

回答

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] 

我相信它取决于你使用此代码,发挥管理,以满足您的需求更好。

+0

Merci mudasobwa。何为provarémes tard! Abraçadades de Barcelona – Ruffeng

+0

De nada!/De res! – mudasobwa