Lisp 中的 json-get 函数



在这一天里,我正在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"))

最新更新