419 Stimmen

Parsen einer JSON-Zeichenkette in Ruby

Ich habe eine Zeichenkette, die ich in Ruby parsen möchte:

string = '{"desc":{"someKey":"someValue","anotherKey":"value"},"main_item":{"stats":{"a":8,"b":12,"c":10}}}'

Gibt es eine einfache Möglichkeit, die Daten zu extrahieren?

7voto

guy mograbi Punkte 24995

Es ist ein bisschen spät, aber ich bin auf etwas Interessantes gestoßen, das mir wichtig zu sein scheint.

Ich habe zufällig diesen Code geschrieben, und er scheint zu funktionieren:

require 'yaml'
CONFIG_FILE = ENV['CONFIG_FILE'] # path to a JSON config file 
configs = YAML.load_file("#{CONFIG_FILE}")
puts configs['desc']['someKey']

Ich war überrascht, dass es funktioniert, da ich die YAML-Bibliothek verwende, aber es funktioniert.

Der Grund, warum dies wichtig ist, ist, dass yaml ist bereits in Ruby integriert, so dass keine Gem-Installation erforderlich ist.

Ich verwende die Versionen 1.8.x und 1.9.x - also die json Bibliothek ist nicht eingebaut, aber sie ist in Version 2.x enthalten.

Technisch gesehen ist dies der einfachste Weg, um die Daten in einer Version kleiner als 2.0 zu extrahieren.

4voto

damianmr Punkte 2459

Ich schlage Oj vor, da es waaaaaay schneller ist als die Standard-JSON-Bibliothek.

https://github.com/ohler55/oj

( siehe Leistungsvergleiche hier )

1voto

Erik Madsen Punkte 1777

Wenn Sie anstelle von OpenStruct in Ihre eigene Klasse deserialisieren möchten, ist es mit wenig Aufwand möglich, das Folgende zu realisieren:

require 'json'
# result is an instance of MyClass
result = JSON.parse(some_json_string, object_class: MyClass)

Alles, was Sie tun müssen, ist, einen Konstruktor mit Null-Argumenten bereitzustellen und die #[]= Methode, die JSON.parse wird anrufen. Wenn Sie sie nicht preisgeben wollen, genügt es, sie privat zu halten:

class MyClass
  attr_reader :a, :b

  private

  def []=(key, value)
    case key
    when 'a' then @a = value
    when 'b' then @b = value
    end
  end
end

Ich probiere es in irb aus:

> JSON.parse('{"a":1, "b":2}', object_class: MyClass)
=> #<MyClass:0x00007fe00913ae98 @a=1, @b=2>

Ein Nachteil dieses Ansatzes ist, dass er nur für flache Strukturen funktioniert, da die object_class sagt dem Parser, welche Klasse er für die Deserialisierung von JSON-Objekten in der Zeichenkette verwenden soll, anstatt Hash (siehe das ähnliche Argument array_class für die analoge Operation für JSON-Arrays). Bei verschachtelten Strukturen bedeutet dies, dass Sie dieselbe Klasse zur Darstellung aller Ebenen verwenden:

> JSON.parse('{"a":1, "b":{ "a": 32 }}', object_class: MyClass)
=> #<MyClass:0x00007fb5110b2b38 @a=1, @b=#<MyClass:0x00007fb5110b2908 @a=32>>

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X