2017-02-02 6 views
1

私はjsonパーサーを実装しようとしていました。入力は、私がこのnilキーはどのようにしてハッシュになりますか?

私は、この

["{", "key", ":", "{", "foo", ":", "bar", ",", "hello", ":", "100", "}", "}"] 

のような配列を取得するためにトークン化

"{key:{foo:bar,hello:100}}" 

にフォーマット

"{ \"key\": { \"foo\": \"bar\", \"hello\" : 100 } }" 

だった私は、あまりにも,を無視している可能性があります。私はその配列からRubyのハッシュを構築しようとしたときとにかく、私はこのnilがキーとして使用されているのか分からない、この

{nil=>{"key"=>{"foo"=>"bar", "hello"=>"100"}}} 

を取得します。これは私が文字がここで何が起こっている文字や数字

def alpha?(s) 
    s.match(/\A[[:alnum:]]+\z/) 
end 

ある場合にtrueを返しalpha?ハッシュ

def build_hash(arr) 
    h = {} 
    keys = [] 
    while arr.size > 0 
    current_token = arr.shift 
    if alpha?(current_token) 
     if keys.empty? # that means a new key is to be expected 
     keys << current_token 
     else 
     h[keys.pop] = current_token 
     end 
    elsif current_token == '}' 
     # these shouldn't be any key left in the keys stack. if there is one, raise error 
     # otherwise close the hash and return from method 
     if not keys.empty? 
     raise_invalid_format_error 
     else 
     return h 
     end 
    elsif current_token == ',' 
     # continue reading. new key will appear. There shouldn't be any key in keys[] 
     raise_invalid_format_error unless keys.empty? 
    elsif current_token == '{' 
     # this means new hash is starting, nested. Should be a value to a key 
     # recursive call, assign the result to the existing key 
     h[keys.pop] = build_hash(arr) 
    end 
    end 
    h 
end 

方法を構築するために使用している方法ですか?

+1

理由だけではない: '(「JSON」)が必要です。 JSON.parse( "{\" key \ ":{\" foo \ "、\" bar \ "、\" hello \ ":100}}"); ' –

+0

@JanZeiseweisええ、私はそれを知っていました。しかし、ライブラリを使用していないことは必要でした – Anwar

+0

最初の要素は '{'(私はアルファが何をしているのかよく分かりません)ですが、 'alpha?'がfalseを返す場合、最後の 'elsif current_token == '{' 'キーが空であるため、' keys.pop'は 'nil'を返します。 @JanZeiseweisああ、 –

答えて

1

私はコメントで説明したように1が存在する場合、キーだけをポップは:

def build_hash(arr) 
    h = {} 
    keys = [] 
    while arr.size > 0 
    current_token = arr.shift 
    if alpha?(current_token) 
     if keys.empty? # that means a new key is to be expected 
     keys << current_token 
     else 
     h[keys.pop] = current_token 
     end 
    elsif current_token == '}' 
     # these shouldn't be any key left in the keys stack. if there is one, raise error 
     # otherwise close the hash and return from method 
     if not keys.empty? 
     raise_invalid_format_error 
     else 
     return h 
     end 
    elsif current_token == ',' 
     # continue reading. new key will appear. There shouldn't be any key in keys[] 
     raise_invalid_format_error unless keys.empty? 
    elsif current_token == '{' 
     # this means new hash is starting, nested. Should be a value to a key 
     # recursive call, assign the result to the existing key 
     if keys.any? 
     h[keys.pop] = build_hash(arr) 
     end 
    end 
    end 
    h 
end 
2

あなたの配列の非常に最初のトークンは、最終的なelsifケースに至るまで落ちる{、次のようになります。keys配列が空である

elsif current_token == '{' 
    # this means new hash is starting, nested. Should be a value to a key 
    # recursive call, assign the result to the existing key 
    h[keys.pop] = .... 

ので、あなたがのためのキーとして使用pop戻りnil、あなたのハッシュ

+0

これを今すぐ入手してください。ありがとう。 upvoted :)私はJanの答えを受け入れました。 – Anwar

関連する問題