【问题标题】:How to concisely map through a list of lists?如何简洁地映射列表列表?
【发布时间】:2012-01-30 07:03:35
【问题描述】:

我正在寻找一种将可变参数函数映射到多个列表的简洁方法,但我不想像使用 MAPCAR 那样将列表作为单独的参数传递,而是希望传递由任意数量的列表组成的单个列表,并通过这些列表进行映射包含列表。我事先不知道封闭列表中有多少个列表,所以我无法解构它。

我尝试以各种方式将 MAPCAR 和 APPLY 结合起来,但无法弄清楚。我必须放弃使用 MAP 并明确地编写迭代吗?

这是一个可以满足我需求的函数:

(defun map-within (fn list-of-lists &optional(maptype #'mapcar))
  "Map FN on the lists contained in LIST-OF-LISTS"
  (cond ((null list-of-lists) nil)
    ((null (cdr list-of-lists)) (car list-of-lists))
    (t
     (funcall maptype fn
         (car list-of-lists)
         (map-within fn (cdr list-of-lists) maptype)))))

在哪里

(map-within #'+ '((1 2 3) (10 20 30) (100 200 300))) => (111 222 333)

有没有什么神奇的 lambda 应用可以用一条线表达出来?

【问题讨论】:

    标签: common-lisp


    【解决方案1】:

    你可以像这样使用apply

    (apply #'mapcar #'+ '((1 2 3) (10 20 30) (100 200 300)))
    => (111 222 333)
    

    【讨论】:

    • 谢谢,这并没有我想象的那么神奇,而且我显然没有想到只是尝试一下。我的想法是 APPLY 接受两个参数,一个函数和一个列表,并将列表元素上的函数称为 args,而实际上它在剩余的 args 上调用该函数,同时特别对待最后一个。
    • @PaulRichter:是的,你应该看看list*
    • 可能仅适用于 CALL-ARGUMENTS-LIMIT 以内的列表,因为该解决方案使用 APPLY
    • 干杯,我不知道我可以用 mapcar 做到这一点
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-06
    • 1970-01-01
    相关资源
    最近更新 更多