2017-11-21 1 views
0

Ich bin ein bisschen Ruby Nooby und kann nicht zu begreifen scheinen, was scheint ein Hash in Array verschachtelt zu sein ?!Ruby Sinatra Hash geschachtelt in Array

wenn ich laufen die folgenden:

widgets = Sinatra::Application.settings.history 
widgets.each do |key, value| 
    puts key 
    puts value 
end 

ich folgendes Ergebnis:

sales31 
data: {"text":"Moeslein Nate","dataImg":"/vinD.jpg","id":"sales31","updatedAt":1511232577} 

jedoch; wenn ich nur die Werte mit dem Schlüssel zu extrahieren versuchen, ich bin mit einem Fehler begegnet:

widgets = Sinatra::Application.settings.history 
widgets.each do |key| 
    puts key[:data] 
end 

Met mit Fehlern TypeError - no implicit conversion of Symbol into Integer

, die mich zu glauben, dass es ein Array mit einer verschachtelten Hash war, so habe ich versucht:

widgets = Sinatra::Application.settings.history 
widgets.each do |key| 
    puts key[0] 
end 

, die gerade die Schlüssel druckt wieder sales30 sales31

und wenn ich versuche, und verschachtelte Daten extrahieren:

widgets = Sinatra::Application.settings.history 
widgets.each do |key| 
    puts key[0][:data] 
end 

Zurück zu Type Error

und nur die ersten Buchstaben des Schlüssels diesmal:

widgets = Sinatra::Application.settings.history 
widgets.each do |key| 
    puts key[0][0] 
end 

jemand am besten erarbeiten kann/Ich kann die Daten so sinnvoll parsen, dass ich mit dem KEY bestimmte Werte extrahieren kann:

widgets[sales31][text] 

, wo es den eigentlichen Text drucken würde:

Moeslein Nate 

Vielen Dank für Ihre Zeit!

+0

Ich denke, ich kann Ihnen helfen, aber können Sie genau sagen, was das Ergebnis sein sollte? Der 'Jeder'-Iterator arbeitet übrigens anders auf Hashes, wenn dem Block ein Argument gegeben wird (in diesem Fall wird er zu einem '' ] 'Array oder zwei Argumenten (in diesem Fall werden sie auf key und val gesetzt) respektive) –

+0

Danke, ja, ich bin in der Lage, dynamisch auf die Elemente wie folgt zugreifen: Hash [Key] [Daten:] [Text:] und haben den Textteil zurückgegeben: "Moeslein Nate" Hash [Key ] [data:] [dataImg:] sollte "/vinD.jpg" zurückgeben Ich möchte die Werte unter Daten geschachtelt bekommen: aber mit Logik als so kann ich sie mit dem Schlüssel erhalten, um sicherzustellen, dass meine Schlüsselwerte übereinstimmen entsprechend! – Shwtm3

+1

basierend auf Ihrer Ruby-Version, oder hinzufügen 'activesupport' als Abhängigkeit können Sie' transform_keys! 'verwenden.So können Sie alle Ihre Schlüssel auf den gleichen Typ (zB Symbol) – marmeladze

Antwort

1

Ich denke, man die Tatsache fehlen, dass Sie eine weitere Ebene der Hash haben in "data"

So ist der richtige Weg für den Zugriff ist:

widgets["sales31"]["data"]["text"] 

somit

widgets = Sinatra::Application.settings.history 
widgets.each do |key, val| 
    puts val["text"] 
end 

seit dem Wert von val ist:

"data": {"text":"Moeslein Nate","dataImg":"/vinD.jpg","id":"sales31","updatedAt":1511232577} 

das ist ein Hash selbst. widgets So ist ein Hash aus:

widgets == {"sales31": "data": {"text": "Moeslein Nate", "dataImg": "/vinD.jpg", "id": "sales31", "updatedAt" :1511232577} } 

widgets["sales31"] == { "data": {"text": "Moeslein Nate", "dataImg": "/vinD.jpg", "id": "sales31", "updatedAt" :1511232577} } 

widgets["sales31"]["data"] == {"text": "Moeslein Nate", "dataImg": "/vinD.jpg", "id": "sales31", "updatedAt" :1511232577} 

widgets["sales31"]["data"]["text"] == "Moeslein Nate" 

Grundsätzlich ein Hash innerhalb eines Hash innerhalb eines Hash.Sie sind nicht ganz klar, wie Sie Ihre Daten formatiert wollen, aber Sie tun können:

widgets = Sinatra::Application.settings.history 
widgets.each do |key, val| 
    puts "widgets[#{key}][#{val.keys[0]}] = #{val[valkeys[0]]["text"]}" 
end 
#=> "widgets["sales31"]["data"] = Moeslein Nate" 

Nun, das ist nicht der schönste Weg, es zu tun, aber da sie eine programmatische Lösung gefragt, es die Aufgabe ohne Nennung Hash-Schlüssel getan ausdrücklich. Es könnte dies vereinfacht werden, wenn es für Sie arbeitet:

widgets = Sinatra::Application.settings.history 
widgets.each do |key, val|  
    puts "widgets[#{key}]["data"] = #{val["data"]["text"]}" 
end 

UPDATE: Dank @marmeladze Kommentar ich die Methode gefunden deep_symbolize_keys kann es mit den ! verwendet werden, um das Original zu ändern, wenn Sie es vorziehen. Ich würde etwas tun wie:

my_widgets = widgets.deep_symbolize_keys 
my_widgets = Sinatra::Application.settings.history 
my_widgets.each do |key, val|  
    puts "widgets[#{key}][:data] = #{val[:data][:text]}" 
end 

Es scheint nur sauberer zu mir nicht zu mischen Schlüsseltypen, es sei denn Sie müssen.

+0

Vielen Dank, Mann, das hat es für mich gelöst! Schätzen Sie das Detail! Ich konnte auch eine Sortierung mit folgendem Befehl durchführen: 'mySortedHash = myJobsHash.sort_by {| k, v | "# {v ['monthTotals']}}"}. reverse' Prost! – Shwtm3