Mar*_*ark 2 lisp list common-lisp repeat
我需要重复列表的每个元素N次,即执行这种转换:
(1 2 3) => (1 1 1 2 2 2 3 3 3) ; N = 3
Run Code Online (Sandbox Code Playgroud)
保持元素的顺序很重要,即第一个元素应该重复N次,然后是第二个,等等.
到目前为止,这是我最好的尝试:
(defun my-fnc (lst &optional (n 2))
(mapcan (lambda (x) (make-list n :initial-element x))
lst))
Run Code Online (Sandbox Code Playgroud)
看起来很有效:
CL-USER> (defparameter *foo* '("foo" "bar"))
*FOO*
CL-USER> (setf *foo* (my-fnc *foo* 3))
("foo" "foo" "foo" "bar" "bar" "bar")
Run Code Online (Sandbox Code Playgroud)
......但不完全.问题是前三个元素是对同一个对象的引用.
("foo" "foo" "foo" "bar" "bar" "bar")
;{---------------} {---------------}
; the same string the same string
Run Code Online (Sandbox Code Playgroud)
这不是我想要的.
所以我的问题是:如何以大多数惯用的方式解决问题,以便结果列表的每个元素都可以引用复制的单独对象.
这通常是不可能的,因为Common Lisp不提供通用的复制功能.此外,
但是,如果您已经解决了问题并提供了复制功能,那就不难了:
(defun my-fnc (list &key (repeat 2) copy-function)
(mapcan (if copy-function
(lambda (x)
(loop :repeat repeat :collect (funcall copy-function x)))
(lambda (x) (make-list n :initial-element x)))
list))
Run Code Online (Sandbox Code Playgroud)
请注意,参数的所有元素list都被复制,即返回值与参数没有交集(在eq测试下并假设copy-function返回一个新对象)