我需要重复列表中的每个元素N次,即执行这种转换:
(1 2 3) => (1 1 1 2 2 2 3 3 3) ; N = 3
保持元素的顺序很重要,即第一个元素应重复N次,然后重复第二次,等等。
这是我迄今为止的最佳尝试:
(defun my-fnc (lst &optional (n 2))
(mapcan (lambda (x) (make-list n :initial-element x))
lst))
看起来很有效:
CL-USER> (defparameter *foo* '("foo" "bar"))
*FOO*
CL-USER> (setf *foo* (my-fnc *foo* 3))
("foo" "foo" "foo" "bar" "bar" "bar")
......但不完全。问题是前三个元素是对同一个对象的引用。
("foo" "foo" "foo" "bar" "bar" "bar")
;{---------------} {---------------}
; the same string the same string
这不是我想要的。
所以我的问题是:如何以大多数惯用的方式解决问题,以便结果列表的每个元素都可以引用复制的单独对象。
答案 0 :(得分:7)
这通常是不可能的,因为Common Lisp不提供通用的复制功能。而且,
fixnum
),无法以任何有意义的意义复制但是,如果你已经解决了问题并提供了复制功能,那就不太难了:
(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))
请注意, all 复制list
参数的元素,即返回值没有带intersection的参数(在eq
测试下)并假设copy-function
返回fresh个对象)