Лисп сопоставляет ключевые слова и находит значения - PullRequest
1 голос
/ 07 марта 2011

Скажите, у меня есть список с ключевыми словами:

'(("element1" :keyword1 "a" :keyword2 "b") 
  ("element2" :keyword3 "c" :keyword4 "d")
  ("element3" :keyword2 "e" :keyword4 "f"))

Какие функции я могу использовать, чтобы найти, какие элементы списка содержат :keyword2 и найти его значение в каждом списке? Я пытаюсь сделать это в Emacs Lisp, но думаю, что с пакетом cl я мог бы адаптировать решение Common Lisp? Я пытался использовать функцию find, как показано здесь , но безрезультатно (конечно, после изменения нескольких элементов синтаксиса для адаптации примеров к Emacs Lisp).

Ответы [ 4 ]

2 голосов
/ 07 марта 2011
(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 голос
/ 24 февраля 2015

Установить 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)
1 голос
/ 07 марта 2011

В 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")
1 голос
/ 07 марта 2011

В lisp вы обычно используете так называемый ассоциативный список (или alist для краткости).Он имеет следующий вид:

  ((key1 . value1) (key2 . value2) (key3 . value3))

Существует ряд функций, предназначенных для работы со списками, включая assq и assoc, которые возвращают пунктирную пару или ноль.

...