Common lisp 只得到一把钥匙

Common lisp 只得到一把钥匙,common-lisp,Common Lisp,我执行以下代码仅检索plist的键: (loop :for (key nil) :on config :by #'cddr :collect key)) 运行此命令将产生: CONFIG-TEST> (loop :for (key nil) :on '(:foo 1 :bar 2) :by #'cddr :collect key) (:FOO :BAR) 有没有比使用循环更“实用”的方法呢?不太可能 CL-USER 35 > (l

我执行以下代码仅检索plist的键:

(loop :for (key nil) :on config :by #'cddr
      :collect key))
运行此命令将产生:

CONFIG-TEST> (loop :for (key nil) :on '(:foo 1 :bar 2) :by #'cddr
                   :collect key)
(:FOO :BAR)
有没有比使用循环更“实用”的方法呢?

不太可能

CL-USER 35 > (let ((? nil))
               (mapcon (lambda (l)
                         (when (setf ? (not ?))
                           (list (first l))))
                       '(:foo 1 :bar 2)))
(:FOO :BAR)
或者可能:

(defun mapncar (fn list &key (start 0) (n 1))
  (loop for l = (nthcdr start list) then (nthcdr n l)
        while l
        collect (funcall fn (first l))))

CL-USER 61 > (mapncar #'identity '(a 1 b 2 c 3) :n 2)
(A B C)

CL-USER 62 > (mapncar #'identity '(a 1 b 2 c 3) :start 1 :n 2)
(1 2 3)
不是真的

CL-USER 35 > (let ((? nil))
               (mapcon (lambda (l)
                         (when (setf ? (not ?))
                           (list (first l))))
                       '(:foo 1 :bar 2)))
(:FOO :BAR)
或者可能:

(defun mapncar (fn list &key (start 0) (n 1))
  (loop for l = (nthcdr start list) then (nthcdr n l)
        while l
        collect (funcall fn (first l))))

CL-USER 61 > (mapncar #'identity '(a 1 b 2 c 3) :n 2)
(A B C)

CL-USER 62 > (mapncar #'identity '(a 1 b 2 c 3) :start 1 :n 2)
(1 2 3)

会给我们带来什么样的风格方向

CL-USER> (do ((result (list) (cons (car plist) result))
              (plist '(:foo 1 :bar 2) (cddr plist)))
             ((null plist) (reverse result)))
(:FOO :BAR)
顺便说一下,我会用更少的语法编写循环,这会影响我吗

CL-USER> (loop for key in '(:foo 1 :bar 2) by 'cddr
               collecting key)
(:FOO :BAR)

会给我们带来什么样的风格方向

CL-USER> (do ((result (list) (cons (car plist) result))
              (plist '(:foo 1 :bar 2) (cddr plist)))
             ((null plist) (reverse result)))
(:FOO :BAR)
顺便说一下,我会用更少的语法编写循环,这会影响我吗

CL-USER> (loop for key in '(:foo 1 :bar 2) by 'cddr
               collecting key)
(:FOO :BAR)
要删除对alexandria的依赖,请定义您自己
plist-alist

(defun plist-alist (l &optional (acc '()))
  (cond ((null l) (nreverse acc))
        (t (plist-alist (cddr l) (cons (cons (car l) (cadr l)) acc)))))
但是,对
:亚历山大港
的依赖不应算作依赖

直接地 实际上,可以更改
plist-alist
定义以仅获取密钥:

(defun plist-keys (l &optional (acc '()))
  (cond ((null l) (nreverse acc))
        (t (plist-keys (cddr l) (cons (car l) acc)))))
同样,价值观:

(defun plist-vals (l &optional (acc '()))
  (cond ((null l) (nreverse acc))
        (t (plist-vals (cddr l) (cons (cadr l) acc)))))
要删除对alexandria的依赖,请定义您自己
plist-alist

(defun plist-alist (l &optional (acc '()))
  (cond ((null l) (nreverse acc))
        (t (plist-alist (cddr l) (cons (cons (car l) (cadr l)) acc)))))
但是,对
:亚历山大港
的依赖不应算作依赖

直接地 实际上,可以更改
plist-alist
定义以仅获取密钥:

(defun plist-keys (l &optional (acc '()))
  (cond ((null l) (nreverse acc))
        (t (plist-keys (cddr l) (cons (car l) acc)))))
同样,价值观:

(defun plist-vals (l &optional (acc '()))
  (cond ((null l) (nreverse acc))
        (t (plist-vals (cddr l) (cons (cadr l) acc)))))

如果确定所有值都不是symbol类型,则可以筛选符号:

(remove-if-not #'symbolp '(:a 1 :b 2)) ;;=> (:A :B)
效率低得多,但通用性强:

  • 用于
    symbolp
    getf
    功能的过滤器 (只有plist中的键可以从plist中获取,因此这是检查它是否为键。但是,检查plist中的元素是否为
    symbolp
    更便宜,并删除大部分非键值, 从而节省时间和成本)

如果确定所有值都不是symbol类型,则可以筛选符号:

(remove-if-not #'symbolp '(:a 1 :b 2)) ;;=> (:A :B)
效率低得多,但通用性强:

  • 用于
    symbolp
    getf
    功能的过滤器 (只有plist中的键可以从plist中获取,因此这是检查它是否为键。但是,检查plist中的元素是否为
    symbolp
    更便宜,并删除大部分非键值, 从而节省时间和成本)

使用SERIES软件包,
scan plist
返回两个系列,一个用于键,另一个用于值:

(scan-plist '(:a 3 :b 2))
=> #Z(:A :B)
   #Z(3 2)
您可以通过此列表收集第一个系列:

(collect 'list (scan-plist '(:a 3 :b 2)))
更一般地说,您可能希望以某种方式处理这些值,因此可以使用
映射
。例如,下面是一个用系列制作的
plist列表

(defun plist-alist (plist)
  (collect 'list
    (mapping (((k v) (scan-plist plist))) (cons k v))))

使用SERIES软件包,
scan plist
返回两个系列,一个用于键,另一个用于值:

(scan-plist '(:a 3 :b 2))
=> #Z(:A :B)
   #Z(3 2)
您可以通过此列表收集第一个系列:

(collect 'list (scan-plist '(:a 3 :b 2)))
更一般地说,您可能希望以某种方式处理这些值,因此可以使用
映射
。例如,下面是一个用系列制作的
plist列表

(defun plist-alist (plist)
  (collect 'list
    (mapping (((k v) (scan-plist plist))) (cons k v))))

使用<强>塞拉比尤姆<强>库,我认为仅次于亚历山大市的第二个:使用<代码> PLIST键< /代码>:

(serapeum:plistkeys'(:a1:b2))
;; (:A:B)

以下是它的实现:

(解除plist键的锁定(plist)
“返回plist的键。”
(收集*
(doplist(k v plist)
(收集k)

也有<代码> PLIST值< /代码>

< P> > <塞拉比尤姆> <强>库,这是仅次于亚历山大市的第二个:使用<代码> PLIST键< /代码>:

(serapeum:plistkeys'(:a1:b2))
;; (:A:B)

以下是它的实现:

(解除plist键的锁定(plist)
“返回plist的键。”
(收集*
(doplist(k v plist)
(收集k)

它还有
plist值

Pfieww。我仍然需要整理一下mapcon的功能:@manfred:MAPCON连接lambda函数结果列表。这允许作为函数返回值的空列表在结果列表中没有任何元素。对于MAPCAR,函数的NIL结果意味着MAPCAR result list.Pfieww中的NIL元素。我仍然需要整理一下mapcon的功能:@manfred:MAPCON连接lambda函数结果列表。这允许作为函数返回值的空列表在结果列表中没有任何元素。对于MAPCAR,函数的NIL结果将意味着MAPCAR结果列表中的NIL元素。最后一个元素看起来比我拥有的元素更简单。@Manfred主要区别是使用as in list,它负责选择剩余列表的第一个元素。最后一个元素看起来比我拥有的元素更简单。@Manfred主要区别是使用for as-in-list,它负责选择剩余列表的第一个元素。从“功能”角度来看,我最喜欢这个。尽管PLIST-ALIST函数似乎不是很有效。从“函数”的角度来看,我最喜欢这个。尽管PLIST-ALIST函数似乎不是很有效。