在这一天里,我正在Prolog和Lisp中解析json。昨天在您的帮助下,我完成了Prolog项目,现在我再次需要帮助。
功能总是json-get,但现在在Lisp中。
这是我写的函子:
(defun json-get (json_obj fields &optional n)
(let ((place (assoc fields json_obj :test 'string=)))
(if (null place)
n
(ns (second place) t)))
函数的行为应与 Prolog 谓词相同。例如,如果输入是:
CL-prompt> (defparameter x (json-parse "{"nome" : "Arthur","cognome" : "Dent"}"))
X
CL-prompt> x
(json-obj ("nome" "Arthur") ("cognome" "Dent"))
输出应为:
CL-prompt> (json-get x "cognome")
"Dent"
相反,如果输入是:
(json-get (json-parse
"{"name" : "Zaphod",
"heads" : [["Head1"], ["Head2"]]}")
"heads" 1 0)
输出应为:
"Head2"
我写的函数完全错了?
P.S. 对于这个项目是禁止的函数,如 SET、SETQ、SETF e MULTIPLE-VALUE-SETQ 和 DO, DO*, DOTIMES, DOLIST e LOOP 和 DEFPARAMETER, DEFVAR e DEFCOSTANT 在一个函数内
谢谢大家
编辑 1:
这是对此功能的描述,
a json-get function that accepts a JSON object
(represented in Common Lisp, as produced by the json_parse function) and a series of
"Fields", retrieve the corresponding object. A field represented by N (with N a number
greater than or equal to 0) represents an index of a JSON array.
编辑 2 :如果我尝试运行 json-get lisp,请回答我:
Error: The variable PLACE is unbound.
你需要递归地实现这一点。您还需要区分 JSON 数组(作为前缀为 json-array
的元素列表实现(和 JSON 对象(作为关联列表实现(。
(defun json-get (json_obj fields)
(if (null fields) ; base case of recursion
json_obj
(let* ((cur-key (car fields))
(current (cond ((and (integerp cur-key)
(eq (car json_obj) 'json-array))
(nth (1+ cur-key) json_obj)) ; add 1 to skip over JSON-ARRAY
((and (stringp cur-key)
(eq (car json_obj) 'json-obj))
(second (assoc cur-key (cdr json_obj) :test #'string=))) ; Use CDR to skip over JSON-OBJ
(t (error "~S is not a JSON object or array or ~s is not appropriate key" json_obj cur-key)))))
(json-get current (cdr fields)))))
fields
必须是字段列表,因此第二个示例是:
(json-get (json-parse
"{"name" : "Zaphod",
"heads" : [["Head1"], ["Head2"]]}")
'("heads" 1 0))
第一个示例应该是:
(json-get x '("cognome"))