这个nil密钥如何进入哈希?

时间:2017-02-02 13:32:13

标签: json ruby parsing

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

var s = document.createElement("script");
s.type = "text/javascript";
s.src = "http://xyz";
$("head").append(s);

我格式化为

"{ \"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 将返回true
alpha?

这里发生了什么?

2 个答案:

答案 0 :(得分:2)

数组中的第一个标记将是{,这将落到最终的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,您将其用作哈希的键。

答案 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