如何在defstruct上执行部分符号匹配?

时间:2010-02-03 00:13:25

标签: elisp common-lisp

在此StackOverFlow question中,我创建了一个员工数据库,并提供了 select-by-first 功能。如果字符串/符号的任何部分匹配,我如何编写 select-by-first-pattern ,其中返回记录?

(select-by-first-pattern 'ev); Returns all records containing "ev" (eg. Steve)

以下是构建数据库所需的代码:(更新:包含建议的解决方案)

(require 'cl)
(defvar *emp-db* nil)
(defun add-record (emp) (push emp *emp-db*))

(defstruct employee age first-name last-name sex children)

(add-record (make-employee))

(add-record (make-employee :age 34
      :last-name 'farquharson
      :first-name 'alice
      :sex 'female))

(add-record (make-employee :age 43
      :last-name 'jobs
      :first-name 'steve
      :sex 'male))

(add-record (make-employee :age 53
      :last-name 'ballmer
      :first-name 'steve
      :sex 'male))

(defun select-by-first (first-name)
  (remove-if-not
   #'(lambda (employee)
       (equal (employee-first-name employee) first-name))
   *emp-db*))

;; ---------- Answer below ----------
;;
(defun select-by-first-pattern (first-name)
  (remove-if-not
   #'(lambda (employee)
       (if (string-match first-name (symbol-name (employee-first-name employee))) t nil))
   *emp-db*))

(print (select-by-first-pattern "al")); Returns alice's record
(print (select-by-first-pattern "ev")); Returns records of the two Steve's
(print (select-by-first-pattern "ee")); Returns nil

2 个答案:

答案 0 :(得分:1)

如果你想做部分或模式匹配,你真的应该使用字符串。我对Common Lisp没有任何经验,但Emacs有很多正则表达式匹配函数。

如果你真的被符号作为输入,你可以使用symbol-name(至少在Elisp中)将符号的名称作为字符串。无论哪种方式,你最终都会比较字符串,所以你不妨开始使用它们。

答案 1 :(得分:0)

使用SYMBOL-NAME将符号转换为字符串,方法是保留原始大小写:

> (symbol-name '|Alice|)
"Alice"

对于简单的字符串搜索,您可以使用SEARCH函数:

> (search "li" (symbol-name '|Alice|))
1
> (search "li" (symbol-name '|Dave|))
NIL

对于复杂的模式匹配,可能this library可以提供帮助。