假设我有一个包含关键字的列表:
'(("element1" :keyword1 "a" :keyword2 "b")
("element2" :keyword3 "c" :keyword4 "d")
("element3" :keyword2 "e" :keyword4 "f"))
我可以使用哪些函数来查找哪些列表元素包含:keyword2
并在每个列表中找到它的值?我试图在Emacs Lisp中这样做,但我认为使用cl
包我可以调整Common Lisp解决方案吗?我试图使用find
函数,如图here所示但无效(当然,在更改一些语法元素以使示例适应Emacs Lisp之后)。
答案 0 :(得分:2)
(require 'cl) (defvar *data* '(("element1" :keyword1 "a" :keyword2 "b") ("element2" :keyword3 "c" :keyword4 "d") ("element3" :keyword2 "e" :keyword4 "f"))) (find :keyword2 *data* :test #'find) ;;=> ("element1" :keyword1 "a" :keyword2 "b") (getf (cdr (find :keyword2 *data* :test #'find)) :keyword2) ;;=> "b" ;; Above only finds the first match; to find all matches, ;; use REMOVE* to remove elements that do not contain the keyword: (remove* :keyword2 *data* :test-not #'find) ;;=> (("element1" :keyword1 "a" :keyword2 "b") ;; ("element3" :keyword2 "e" :keyword4 "f")) (mapcar (lambda (x) (getf (cdr x) :keyword2)) (remove* :keyword2 *data* :test-not #'find)) ;;=> ("b" "e")
答案 1 :(得分:1)
在lisp中,您通常会使用所谓的关联列表(或简称 alist )。它具有以下形式:
((key1 . value1) (key2 . value2) (key3 . value3))
有许多功能可以与alist一起使用,包括assq
和assoc
,它们返回虚线对,或者为nil。
答案 2 :(得分:1)
在Common Lisp中,通常在这种情况下使用destructuring-bind提取值,类似于
(destructuring-bind (string &key keyword2 &allow-other-keys)
'("element1" :keyword1 "a" :keyword2 "b")
(list string keyword2)) ; or do anything with string and keyword2
应该导致
("element1" "b")
答案 3 :(得分:1)
安装dash
列表操作库(GitHub链接包含说明)。它包含许多有用的功能来实现任何目标。假设您的上面的列表名为data
,那么您可以:
(--find-indices (-elem-indices :keyword2 it) data) ; => (0 2)
(--map (cadr (--drop-while (not (eq :keyword2 it)) it)) data) ; => ("b" nil "e")
(--map-indexed (cons it-index ; => ((0 . "b") (1) (2 . "e"))
(cadr (--drop-while (not (eq :keyword2 it)) it))) data)