检查子列表中具有值的关键字的出现
Check occurrence of keyword with value in sublist
我有一个数据结构,由 属性 个列表中的列表组成,列表本身在列表中。本质上是 plist 的二维矩阵。它的形式是:
(((:VALUE 0 :GROUP 0) (:VALUE 0 :GROUP 0))
((:VALUE 0 :GROUP 0) (:VALUE 0 :GROUP 0))
((:VALUE 0 :GROUP 0) (:VALUE 0 :GROUP 0)))
每个 :value 和 :group 将包含一个任意整数值。我需要查找是否有任何 :group 关键字为 0。我一直在尝试使用 member
函数来实现此目的,但它仅 returns nil
.
我的代码,假设数据结构被称为 data
,是:
(member '(:group 0) data :test 'equal))
如何使用 member
函数来检查 :group 0
在子列表的子列表中的出现? (如果确实可以的话,还是我应该只使用几个循环来迭代?)
试试 getf
作为
find
/find-if
and/or remove
/remove-if-not
:
一级嵌套
准备数据
(defparameter *data-1*
(loop repeat 10 collect (list :value (random 10) :group (random 10))))
*data-1*
((:VALUE 7 :GROUP 4) (:VALUE 9 :GROUP 6) (:VALUE 2 :GROUP 7) (:VALUE 8 :GROUP 2)
(:VALUE 5 :GROUP 6) (:VALUE 4 :GROUP 7) (:VALUE 3 :GROUP 5) (:VALUE 8 :GROUP 7)
(:VALUE 0 :GROUP 3) (:VALUE 5 :GROUP 5))
A:找到组 7 的 1st 出现:
(find 7 *data-1* :key (lambda (pl) (getf pl :group)))
==> (:VALUE 2 :GROUP 7)
B:查找 所有 组 7 的出现:
(remove 7 *data-1* :key (lambda (pl) (getf pl :group)) :test-not #'eql)
==> ((:VALUE 2 :GROUP 7) (:VALUE 4 :GROUP 7) (:VALUE 8 :GROUP 7))
二级嵌套
准备数据:
(defparameter *data-2*
(loop repeat 10 collect
(loop repeat (random 4) collect
(list :value (random 10) :group (random 10)))))
*data-2*
(((:VALUE 9 :GROUP 9) (:VALUE 8 :GROUP 2) (:VALUE 6 :GROUP 7)) NIL
((:VALUE 9 :GROUP 5)) ((:VALUE 9 :GROUP 1)) NIL
((:VALUE 2 :GROUP 7) (:VALUE 6 :GROUP 5) (:VALUE 2 :GROUP 1))
((:VALUE 1 :GROUP 4) (:VALUE 5 :GROUP 5))
((:VALUE 9 :GROUP 7) (:VALUE 9 :GROUP 8) (:VALUE 7 :GROUP 4))
((:VALUE 4 :GROUP 7)) NIL)
C:找到组 7 的 1st 出现:
(find-if (lambda (l)
(find 7 l :key (lambda (pl) (getf pl :group))))
*data-2*)
==> ((:VALUE 9 :GROUP 9) (:VALUE 8 :GROUP 2) (:VALUE 6 :GROUP 7))
D:查找 所有 组 7 的出现:
(remove-if-not (lambda (l)
(find 7 l :key (lambda (pl) (getf pl :group))))
*data-2*)
==>
(((:VALUE 9 :GROUP 9) (:VALUE 8 :GROUP 2) (:VALUE 6 :GROUP 7))
((:VALUE 2 :GROUP 7) (:VALUE 6 :GROUP 5) (:VALUE 2 :GROUP 1))
((:VALUE 9 :GROUP 7) (:VALUE 9 :GROUP 8) (:VALUE 7 :GROUP 4))
((:VALUE 4 :GROUP 7)))
定义函数:
根据您的需要,您可能想要定义函数
(defun get-group (plist)
(getf plist :group))
(defun find-group (list-of-plists group)
(find group list-of-plists :key #'get-group))
(defun make-group-finder (group)
(lambda (list-of-plists) (find-group list-of-plists group)))
现在您可以将它们用于上述任务:
A: (find-group *data-1* 7)
B: (remove 7 *data-1* :key #'get-group :test-not #'eql)
C: (find-if (make-group-finder 7) *data-2*)
D: (remove-if-not (make-group-finder 7) *data-2*)
PS remove-if-not
是 "filter".
的 Lisp 习语
我有一个数据结构,由 属性 个列表中的列表组成,列表本身在列表中。本质上是 plist 的二维矩阵。它的形式是:
(((:VALUE 0 :GROUP 0) (:VALUE 0 :GROUP 0))
((:VALUE 0 :GROUP 0) (:VALUE 0 :GROUP 0))
((:VALUE 0 :GROUP 0) (:VALUE 0 :GROUP 0)))
每个 :value 和 :group 将包含一个任意整数值。我需要查找是否有任何 :group 关键字为 0。我一直在尝试使用 member
函数来实现此目的,但它仅 returns nil
.
我的代码,假设数据结构被称为 data
,是:
(member '(:group 0) data :test 'equal))
如何使用 member
函数来检查 :group 0
在子列表的子列表中的出现? (如果确实可以的话,还是我应该只使用几个循环来迭代?)
试试 getf
作为
find
/find-if
and/or remove
/remove-if-not
:
一级嵌套
准备数据
(defparameter *data-1*
(loop repeat 10 collect (list :value (random 10) :group (random 10))))
*data-1*
((:VALUE 7 :GROUP 4) (:VALUE 9 :GROUP 6) (:VALUE 2 :GROUP 7) (:VALUE 8 :GROUP 2)
(:VALUE 5 :GROUP 6) (:VALUE 4 :GROUP 7) (:VALUE 3 :GROUP 5) (:VALUE 8 :GROUP 7)
(:VALUE 0 :GROUP 3) (:VALUE 5 :GROUP 5))
A:找到组 7 的 1st 出现:
(find 7 *data-1* :key (lambda (pl) (getf pl :group)))
==> (:VALUE 2 :GROUP 7)
B:查找 所有 组 7 的出现:
(remove 7 *data-1* :key (lambda (pl) (getf pl :group)) :test-not #'eql)
==> ((:VALUE 2 :GROUP 7) (:VALUE 4 :GROUP 7) (:VALUE 8 :GROUP 7))
二级嵌套
准备数据:
(defparameter *data-2*
(loop repeat 10 collect
(loop repeat (random 4) collect
(list :value (random 10) :group (random 10)))))
*data-2*
(((:VALUE 9 :GROUP 9) (:VALUE 8 :GROUP 2) (:VALUE 6 :GROUP 7)) NIL
((:VALUE 9 :GROUP 5)) ((:VALUE 9 :GROUP 1)) NIL
((:VALUE 2 :GROUP 7) (:VALUE 6 :GROUP 5) (:VALUE 2 :GROUP 1))
((:VALUE 1 :GROUP 4) (:VALUE 5 :GROUP 5))
((:VALUE 9 :GROUP 7) (:VALUE 9 :GROUP 8) (:VALUE 7 :GROUP 4))
((:VALUE 4 :GROUP 7)) NIL)
C:找到组 7 的 1st 出现:
(find-if (lambda (l)
(find 7 l :key (lambda (pl) (getf pl :group))))
*data-2*)
==> ((:VALUE 9 :GROUP 9) (:VALUE 8 :GROUP 2) (:VALUE 6 :GROUP 7))
D:查找 所有 组 7 的出现:
(remove-if-not (lambda (l)
(find 7 l :key (lambda (pl) (getf pl :group))))
*data-2*)
==>
(((:VALUE 9 :GROUP 9) (:VALUE 8 :GROUP 2) (:VALUE 6 :GROUP 7))
((:VALUE 2 :GROUP 7) (:VALUE 6 :GROUP 5) (:VALUE 2 :GROUP 1))
((:VALUE 9 :GROUP 7) (:VALUE 9 :GROUP 8) (:VALUE 7 :GROUP 4))
((:VALUE 4 :GROUP 7)))
定义函数:
根据您的需要,您可能想要定义函数
(defun get-group (plist)
(getf plist :group))
(defun find-group (list-of-plists group)
(find group list-of-plists :key #'get-group))
(defun make-group-finder (group)
(lambda (list-of-plists) (find-group list-of-plists group)))
现在您可以将它们用于上述任务:
A: (find-group *data-1* 7)
B: (remove 7 *data-1* :key #'get-group :test-not #'eql)
C: (find-if (make-group-finder 7) *data-2*)
D: (remove-if-not (make-group-finder 7) *data-2*)
PS remove-if-not
是 "filter".