2017-09-14 6 views
-1

Ich habe dieses Array [{:foo=>[{:bar=>[:baz]}]}, :foo, {:foo=>[{:bar=>[:bat]}]}, :bar] Wie Sie sehen können, gibt es Symbole und Hashes. Was ich versuche zu tun ist, Wiederholungen für jeden Schlüssel oder Schlüssel innerhalb von Werten zu vermeiden. Meine gewünschte Ausgabe ist:Konvertieren Array von Hashes und Symbolen in Unique

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

Wie Sie sehen können, gibt es keine Wiederholung von Schlüssel foo oder Wiederholung von foo => bar.

Ich habe stundenlang auf diesem einen stecken und ich kann es nicht erreichen. Irgendeine Idee?

+0

Rekursive Iteration durch Hash-Werte würde _amost_ tun. Das Ding ist das Problem wie gesagt ** hat keine Lösung **. Denken Sie an '{foo: [: bar]}, {foo: {bar: [: baz]}}'. – mudasobwa

+0

Ja, genau das passiert mir. Ich verstehe es fast, aber ich bekomme nie die endgültige Lösung. – Ruffeng

+0

Vielleicht ist mein Problem im Moment, dass ich dieses spezifische Array baue, weil ich von einem Array komme ("foo.bar.baz, foo, foo.bar.bat, bar") – Ruffeng

Antwort

0

Die unten würde irgendwie funktionieren:

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 
} 

Die oben bereits mehr oder weniger akzeptablen Ergebnis führt:

puts (built = builder.(input)).inspect 
#⇒ {:foo=>{:bar=>{:baz=>{}, :bat=>{}}}, :bar=>{}} 

genau zurückzukehren, was man wollte man muss Kette lambda (es gibt keine Möglichkeit, im Voraus zu sagen, ob das Objekt ein Blatt ist oder nicht):

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] 

ich es glaube

+0

Merci mudasobwa. Ho provare me tard! Abraçada des Barcelona – Ruffeng

+0

De nada!/De res! – mudasobwa