2017-01-21 3 views
0

Ich brauche alle Werte von 'Name' Schlüssel und gleichzeitig, um Werte von 'Kinder' Schlüssel zu bekommen. Ich bin in der Lage, nur 'Namen' von der ersten Ebene abzurufen, aber mit 'Kindern', da nicht alle 'Namen' sie haben.Wie kann ich spezifische Schlüsselwerte von json erhalten?

puts data['labels'].collect { |item| item['name'] } 

Die JSON Antwort ist die folgende:

{"labels": [{ 
    "name": "Crime" 
}, { 
    "name": "Demonstrations" 
}, { 
    "name": "Music", 
    "children": [{ 
     "name": "Awards" 
    }, { 
     "name": "Classical" 
    }, { 
     "name": "Country" 
    }, { 
     "name": "Other" 
    }, { 
     "name": "Pop" 
    }, { 
     "name": "Soul" 
    }, { 
     "name": "X Factor" 
    }] 
}, { 
    "name": "Politics" 
}, { 
    "name": "Rescue" 
}, { 
    "name": "Special Events" 
}, { 
    "name": "Sports", 
    "children": [{ 
     "name": "Auto Racing" 
    }, { 
     "name": "Awards" 
    }, { 
     "name": "Baseball" 
    }, { 
     "name": "Basketball" 
    }, { 
     "name": "NASCAR (Cup)" 
    }, { 
     "name": "NASCAR (Nationwide)" 
    }, { 
     "name": "NASCAR (Truck)" 
    }, { 
     "name": "NASCAR (XFINITY)" 
    }, { 
     "name": "Other" 
    }, { 
     "name": "Rodeo" 
    }, { 
     "name": "Rugby" 
    }, { 
     "name": "Running" 
    }, { 
     "name": "Sailing" 
    }, { 
     "name": "Skating" 
    }, { 
     "name": "Volleyball" 
    }] 
}, { 
    "name": "Traffic" 
}, { 
    "name": "Weather" 
}]} 

Antwort

2
puts data['labels'].collect { |item| item['name'] } 

wird einen Fehler werfen

NoMethodError: undefined method `map' for nil:NilClass 

da Ihre Schlüssel Symbole sind, keine Strings.

Auch

und zugleich Werte von ‚Kinder‘ Schlüssel

zu erhalten Sind Sie sicher, dass Sie die Schlüssel zu bekommen? Weil alle Schlüssel identisch sind (:name). Vielleicht brauchen Sie Werte? Wie auch immer, wenn Sie Schlüssel benötigen, ändern Sie einfach die values zu keys in Lösung unten.

Jetzt Lösung (unter Verwendung von sicherem Navigator (&)):

data[:labels].map { |item| [item[:name], item[:children]&.map(&:values)] } 
# => [["Crime", nil], 
#  ["Demonstrations", nil], 
#  ["Music", ["Awards", "Classical", "Country", "Other", "Pop", "Soul", "X Factor"]], 
#  ["Politics", nil], 
#  ["Rescue", nil], 
#  ["Special Events", nil], 
#  ["Sports", ["Auto Racing", "Awards", "Baseball", "Basketball", "NASCAR (Cup)", "NASCAR (Nationwide)", "NASCAR (Truck)", "NASCAR (XFINITY)", "Other", "Rodeo", "Rugby", "Running", "Sailing", "Skating", "Volleyball"]], 
#  ["Traffic", nil], 
#  ["Weather", nil] 
# ] 

Die obige Lösung ohne sicheren Navigator:

data[:labels].map { |item| [item[:name], item[:children] ? item[:children].map(&:values) : nil] } 
+0

Andrey, p data ['labels']. Sammeln {| item | item ['name']} gibt für mich keinen Fehler aus, sondern erfasst nur die Werte aller 'Namen', ignoriert aber 'Name', die mit 'Kinder' zusammenhängen. Ich bin auf Ruby 2.1.2 und sichere Navigation Operator wird in meinem Fall nicht unterstützt (( –

+0

@DenisS. Ich habe die Antwort bearbeitet –

+0

Vielen Dank, Andrey! Das ist genau das, was ich versuchte zu bekommen! –

1

Wenn h Ihre Hash sind, könnten Sie schreiben

h[:labels].map do |f| 
    g = { name: f[:name] } 
    f.key?(:children) ? g.merge(children: f[:children].flat_map(&:values)) : g 
end 
    #=> [{:name=>"Crime"}, 
    # {:name=>"Demonstrations"}, 
    # {:name=>"Music", 
    #  :children=>["Awards", "Classical", "Country", "Other", "Pop", "Soul", "X Factor"] 
    # }, 
    # {:name=>"Politics"}, 
    # {:name=>"Rescue"}, 
    # {:name=>"Special Events"}, 
    # {:name=>"Sports", 
    #  :children=>["Auto Racing", "Awards", "Baseball", "Basketball", "NASCAR (Cup)", 
    #     "NASCAR (Nationwide)", "NASCAR (Truck)", "NASCAR (XFINITY)", "Other", 
    #     "Rodeo", "Rugby", "Running", "Sailing", "Skating", "Volleyball"] 
    # }, 
    # {:name=>"Traffic"}, 
    # {:name=>"Weather"} 
    # ] 

Dies verwendet die Methoden Hash#key?, Hash#merge, Enumerable#flat_map und ein paar häufiger.

+0

Danke Cary , aber leider bin ich auf Ruby 2.1.2 und sicherer Navigationsoperator wird in meinem Fall nicht unterstützt. (( –

+0

Denis, ich habe den sicheren Navigationsoperator nicht benutzt. Vielleicht beabsichtigten Sie Ihren Kommentar für @Andrey. –

+0

oooops, mein böse Cary. Sie haben Recht) Ich schätze Ihre Antwort) Danke –

Verwandte Themen