【问题标题】:Looking for a way to map a function over a 2D Lisp array寻找一种将函数映射到 2D Lisp 数组的方法
【发布时间】:2017-07-19 13:45:45
【问题描述】:

mapcarmapcanmapc 等所有映射函数都需要列表作为输入。我正在使用 2D 数组,并且鉴于通常较大的尺寸(有时为 50,000 x 1,000),我宁愿不要弄乱我的数组的等级。

我需要一种方法来将(log n) 之类的函数应用于二维数组中的每个元素并生成一个二维数组。

非常感谢任何帮助或指导。

在 AllegroCL (Common Lisp) 中工作

【问题讨论】:

    标签: arrays common-lisp


    【解决方案1】:

    你需要的是一个组合

    类似这样的:

    (defun array-map (function array
                      &optional (retval (make-array (array-dimensions array))))
      "Apply FUNCTION to each element of ARRAY.
    Return a new array, or write into the optional 3rd argument."
      (dotimes (i (array-total-size array) retval)
        (setf (row-major-aref retval i)
              (funcall function (row-major-aref array i)))))
    

    例子:

    (defparameter a (make-array '(2 3) :initial-contents '((1 2 3) (4 5 6))))
    a
    ==> #2A((1 2 3) (4 5 6))
    (array-map #'sqrt a)
    ==> #2A((1 1.4142135 1.7320508) (2 2.236068 2.4494898))
    a ; does not change!
    ==> #2A((1 2 3) (4 5 6))
    

    你也可以使用类似于map-intoarray-map

    (array-map #'1+ a a)
    ==> #2A((2 3 4) (5 6 7))
    a   ; modified, no new storage is allocated
    ==> #2A((2 3 4) (5 6 7))
    

    注意array-map 可以处理任何数组维度,从向量到矩阵再到 10d 等。

    练习:实现array-multi-map 接受任意数量的参数和任意数量的数组的函数,以便

    (array-multi-map #'+ #A((1 2 3) (4 5 6)) #A((11 22 33) (44 55 66)))
    ==> #A((12 24 36) (48 60 72))
    

    附言。整个CLHS Chapter 15 ArraysCLtL2 Chapter 17 Arrays都值得研究。

    【讨论】:

    • 最好让用户指定新数组的元素类型。
    • @jkiiski:我考虑过,但决定不这样做。如果用户想要这种级别的控制,他可以通过retval。从参数数组类型推断数组类型可能会阻止sqrt 示例工作,因为输入数组可能专门用于整数。
    • 这很棒。谢谢你。尽管功能更复杂,但我喜欢它非常简单且易于实现。
    猜你喜欢
    • 2013-11-17
    • 1970-01-01
    • 1970-01-01
    • 2011-02-15
    • 1970-01-01
    • 2011-06-01
    • 2011-07-23
    • 2021-07-24
    • 1970-01-01
    相关资源
    最近更新 更多