【问题标题】:Mapcar and assoc地图车和副驾驶
【发布时间】:2011-06-17 22:21:30
【问题描述】:

我想做:

(mapcar #'assoc '(a s) '((a . b) (c . d) (s . f)))

并让它返回

((A . B) (S . F))

这似乎很合理,考虑到(assoc 'a '((a . b) (c . d) (s . f))) 返回(A . B)(assoc 's '((a . b) (c . d) (s . f))) 返回(S . F)。但可惜它不起作用:

*** - ASSOC: A is not a list
The following restarts are available:
ABORT          :R1      Abort main loop

有什么想法吗?

【问题讨论】:

    标签: lisp common-lisp clisp


    【解决方案1】:

    当与两个列表一起使用时,mapcar 将函数成对地应用于列表(对于三个列表,它会将它们应用于三重等)。所以

    (mapcar #'assoc '(a s) '((a . b) (c . d) (s . f)))
    

    相同
    ( (assoc 'a (a . b)) (assoc 's (c . d)) )
    

    (当与不同长度的列表一起使用时,mapcar 使用最小列表的大小)。要得到你想要的,你应该这样做:

    (mapcar (lambda (x) (assoc x '((a . b) (c . d) (s . f)))) '(a s))
    

    【讨论】:

      【解决方案2】:

      我们需要另一个列表级别。第二个参数应该是关联列表的列表。

      CL-USER >  (mapcar #'assoc '(a s) '(((a . b) (c . d) (s . f))))
      
      ((A . B))
      

      但第二个参数只有一个元素长。现在我们可以使用一个技巧,让它成为一个循环列表:

      CL-USER > (mapcar #'assoc '(a s) '#1=(((A . B) (C . D) (S . F)) . #1#))
      
      ((A . B) (S . F))
      

      如果我们为第二个参数构造一个循环列表,那么它就可以工作。

      作为一个函数:

      (defun circular (list)
        (if (null list)
            list
          (setf (cdr (last list)) list)))
      
      CL-USER > (mapcar #'assoc '(a s) (circular '(((a . b) (c . d) (s . f)))))
      
      ((A . B) (S . F))
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2022-11-21
        • 1970-01-01
        • 2013-05-22
        • 2018-08-26
        • 2022-07-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多