Json 这个nil键是如何进入散列的?

Json 这个nil键是如何进入散列的?,json,ruby,parsing,Json,Ruby,Parsing,我试图实现一个json解析器。输入是 "{ \"key\": { \"foo\": \"bar\", \"hello\" : 100 } }" 我把它格式化成 "{key:{foo:bar,hello:100}}" 然后我将其标记化以获得如下数组 ["{", "key", ":", "{", "foo", ":", "bar", ",", "hello", ":", "100", "}", "}"] 我可能也忽略了,。不管怎样,当我试图从那个数组构建ruby哈希时,我得到了这个结果 {ni

我试图实现一个json解析器。输入是

"{ \"key\": { \"foo\": \"bar\", \"hello\" : 100 } }"
我把它格式化成

"{key:{foo:bar,hello:100}}"
然后我将其标记化以获得如下数组

["{", "key", ":", "{", "foo", ":", "bar", ",", "hello", ":", "100", "}", "}"]
我可能也忽略了
。不管怎样,当我试图从那个数组构建ruby哈希时,我得到了这个结果

{nil=>{"key"=>{"foo"=>"bar", "hello"=>"100"}}}
我不知道这个
nil
是如何被用作键的。这是我用来构建散列的方法

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

这是怎么回事

数组中的第一个标记将是
{
,这将贯穿到最后的
elsif
案例:

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] = ....

keys
数组是空的,因此
pop
返回
nil
,您将其用作哈希的键。

如我在注释中所述,只有在存在一个键时才弹出一个键:

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
def build_散列(arr)
h={}
键=[]
当arr.size>0时
当前_标记=arr.shift
如果alpha?(当前_令牌)
如果keys.empty?#这意味着需要一个新密钥

键为什么不简单:
require('json');json.parse({“key\”:{“foo\”:“bar\”,“hello\”:100}”);
@JanZeiseweis是的,我知道。但是不使用任何库是一个必需的部分,第一个元素是“{”(我不确定alpha?在做什么)但是如果
alpha?
返回false,则跳到最后一个
elsif current_token='{'
,由于键是空的,
keys.pop
返回
nil
@JanZeiseweis噢。我忘记了
alpha?
,如果它是最后一个
elsif
中的字母或数字,则返回true,您应该只执行
h[keys.pop]=build_hash(arr)
只有当你的密钥不是空的;)现在就知道了。谢谢。投票结果:)我接受了简的答案,因为他第一次在评论中回答了这个问题。
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