lisp - 在 Common Lisp 中访问 Assoc 列表的更好方法

标签 lisp common-lisp

我有一个正在开发的天气预报应用程序,但我在使用关联列表时遇到了一些麻烦。我使用 openweathermap 和 convert-to-json 从我的 get-weather 函数返回了以下列表:

((:COORD (:LON . -123.12) (:LAT . 49.25))
 (:WEATHER
  ((:ID . 500) (:MAIN . "Rain") (:DESCRIPTION . "light rain") (:ICON . "10n")))
 (:BASE . "cmc stations")
 (:MAIN (:TEMP . 281.56) (:PRESSURE . 1001) (:HUMIDITY . 93)
  (:TEMP--MIN . 276.15) (:TEMP--MAX . 283.15))
 (:WIND (:SPEED . 3.1) (:DEG . 100)) (:CLOUDS (:ALL . 90)) (:DT . 1453467600)
 (:SYS (:TYPE . 1) (:ID . 3359) (:MESSAGE . 0.0039) (:COUNTRY . "CA")
  (:SUNRISE . 1453478139) (:SUNSET . 1453510389))
 (:ID . 6173331) (:NAME . "Vancouver") (:COD . 200))

我正在尝试访问 :weather :main rain。目前我在做:

(cdr (second (second (assoc :weather *assoc-list-from-above*))))

有没有更好的办法?

最佳答案

虽然我非常喜欢@jkiiski 的json-bind 解决方案,但我想我也应该添加以下选项。

如果查询路径在编译时已知,您可以使用下面的宏

(defmacro report-get (report &optional key &rest keys)
  (cond
   ((null key) report)
   ((integerp key) `(report-get (nth ,key ,report)  ,@keys))
   (t `(report-get (cdr (assoc ,key ,report)) ,@keys))))

例子:

CL-USER> (report-get *array-from-above* :weather 0 :main)
"Rain"

CL-USER> (report-get *array-from-above* :coord :lon)
-123.12

CL-USER> (macroexpand '(report-get *array-from-above* :weather 0 :main))
(CDR (ASSOC :MAIN (NTH 0 (CDR (ASSOC :WEATHER *ARRAY-FROM-ABOVE*)))))
T

(report-get *array-from-above* :weather 0 :main) 中的 0 是访问天气项目集合中的第一项

编辑:忘记提及 - 这个宏是setf-able。

CL-USER> (report-get *array-from-above* :weather 0 :main)
"Rain"
CL-USER> (setf (report-get *array-from-above* :weather 0 :main) "Sunny")
"Sunny"
CL-USER> (report-get *array-from-above* :weather 0 :main)
"Sunny"

可能对您的要求没有用,但很高兴知道。

关于lisp - 在 Common Lisp 中访问 Assoc 列表的更好方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34948131/

相关文章:

javascript - 程序化非尾递归消除

lisp - 试图计算总工资

lisp - 调用参数应为结构实例的函数

common-lisp - 使用 Ironclad 和 Flexi-stream 进行哈希处理

lisp - 剪辑 : variable has no value

lisp - 忽略maphash lambda函数中的参数

erlang - erlang 中的 cond 样式语句

python - SBCL 运行 Shell 命令

lisp - sw-http 中关于 APPLICATION-FINDER-FN 的详细信息

winapi - CFFI 和 win32 剪贴板访问