2017-09-14 65 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

相關問題