2012-02-20 7 views
16

私はnet/httpを使用して、Yahoo Placemaker APIからjsonデータを取得しています。応答を受け取った後、私は応答でJSON.parseを実行しています。私はjsonResponse['version']のようなものを実行して要素にアクセスすることができるが、私はjsonResponse.versionを行うことができないのですruby​​ハッシュにドットシンタックスを使用できません

{"processingTime"=>"0.001493", "version"=>"1.4.0.526 build 111113", "documentLength"=>"25", "document"=>{"administrativeScope"=>{"woeId"=>"2503863", "type"=>"Town", "name"=>"Tampa, FL, US", "centroid"=>{"latitude"=>"27.9465", "longitude"=>"-82.4593"}}, "geographicScope"=>{"woeId"=>"2503863", "type"=>"Town", "name"=>"Tampa, FL, US", "centroid"=>{"latitude"=>"27.9465", "longitude"=>"-82.4593"}}, "localScopes"=>{"localScope"=>{"woeId"=>"2503863", "type"=>"Town", "name"=>"Tampa, FL, US (Town)", "centroid"=>{"latitude"=>"27.9465", "longitude"=>"-82.4593"}, "southWest"=>{"latitude"=>"27.8132", "longitude"=>"-82.6489"}, "northEast"=>{"latitude"=>"28.1714", "longitude"=>"-82.2539"}, "ancestors"=>[{"ancestor"=>{"woeId"=>"12587831", "type"=>"County", "name"=>"Hillsborough"}}, {"ancestor"=>{"woeId"=>"2347568", "type"=>"State", "name"=>"Florida"}}, {"ancestor"=>{"woeId"=>"23424977", "type"=>"Country", "name"=>"United States"}}]}}, "extents"=>{"center"=>{"latitude"=>"27.9465", "longitude"=>"-82.4593"}, "southWest"=>{"latitude"=>"27.8132", "longitude"=>"-82.6489"}, "northEast"=>{"latitude"=>"28.1714", "longitude"=>"-82.2539"}}, "placeDetails"=>{"placeId"=>"1", "place"=>{"woeId"=>"2503863", "type"=>"Town", "name"=>"Tampa, FL, US", "centroid"=>{"latitude"=>"27.9465", "longitude"=>"-82.4593"}}, "placeReferenceIds"=>"1", "matchType"=>"0", "weight"=>"1", "confidence"=>"8"}, "referenceList"=>{"reference"=>{"woeIds"=>"2503863", "placeReferenceId"=>"1", "placeIds"=>"1", "start"=>"15", "end"=>"20", "isPlaintextMarker"=>"1", "text"=>"Tampa", "type"=>"plaintext", "xpath"=>""}}}} 

:これは私のように見えるハッシュを提供します。どうしてこれなの?

+0

私はRubyがそれをサポートしているとは思わない。 –

答えて

42

Hashはそれのキーのドット構文を持っていないこれを行うことができません。 OpenStructはありません:

require 'ostruct' 
hash = {:name => 'John'} 
os = OpenStruct.new(hash) 
p os.name #=> "John" 
+0

os.name.firstnameは動作していないようですが、os.nameは通常のハッシュを返します。 – teknopaul

+0

これはネストされたハッシュや配列に対しては機能しません。下のwhodabuddaの答えを参照してください。 –

5

これはJavaScript機能であり、Ruby機能ではありません。 Rubyでは、「ドット構文」を使用するために、オブジェクトはそれらのメソッドに応答する必要があります。 Rubyハッシュは#[](key)メソッドを使用して要素にアクセスします。

4

なぜ、あなたはメタプログラミングを経由して

module LookLikeJSON 
    def method_missing(meth, *args, &block) 
    if has_key?(meth.to_s) 
     self[meth.to_s] 
    else 
     raise NoMethodError, 'undefined method #{meth} for #{self}' 
    end 
    end 
end 

h = {"processingTime"=>"0.001493", "version"=>"1.4.0.526 build 111113", "documentLength"=>"25"} 
h.extend(LookLikeJSON) 
h.processingTime #=> "0.001493" 
+2

ですが、どうして気になるのですか? – d11wtq

+1

+1:それはまさに私がやることです! :) –

+0

文字列を一重引用符で補間しますか? :/そして 'stringify_keys! 'を使って最初にキーを正規化します。 –

0

Hashversionメソッドを持っていないので。

8

HashDot宝石がこれに適しています。

ハッシュドットでは、ハッシュにドット表記構文を使用できます。 JSON.parseで再解析されたjson文字列でも動作します。

require 'hash_dot' 

hash = {b: {c: {d: 1}}}.to_dot 
hash.b.c.d => 1 

json_hash = JSON.parse(hash.to_json) 
json_hash.b.c.d => 1 
+0

素敵な宝石!ありがとう! – Richard

9

OpenStructは、純粋なハッシュのためにうまく動作しますが、埋め込ま配列や他のハッシュとハッシュのために、ドット構文はチョークます。私は別の宝石にロードすることなく、うまく機能し、このソリューション、出くわした: https://coderwall.com/p/74rajw/convert-a-complex-nested-hash-to-an-object 基本的な手順は以下のとおりです。

data = YAML::load(File.open("your yaml file")) 
json_data = data.to_json 
mystr = JSON.parse(json_data,object_class: OpenStruct) 

あなたは今、ドット構文を使用してmystr内のすべてのオブジェクトにアクセスすることができます。

+0

"JSONとOpenStructの両方がRuby標準ライブラリにあるため、サードパーティの依存関係はありません。 –

+0

これは最良の回答であり、受け入れられるべきです。 –

関連する問題