Lisp匹配关键字并查找值

时间:2011-03-07 07:58:15

标签: lisp elisp

假设我有一个包含关键字的列表:

'(("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之后)。

4 个答案:

答案 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一起使用,包括assqassoc,它们返回虚线对,或者为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)