List 通过复制重复列表中的元素
我需要将列表中的每个元素重复N次,即执行这种转换:List 通过复制重复列表中的元素,list,lisp,common-lisp,repeat,List,Lisp,Common Lisp,Repeat,我需要将列表中的每个元素重复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&g
(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
这不是我想要的
所以我的问题是:如何以最惯用的方式解决这个问题,使结果列表的每个元素都引用复制的单独对象。这通常是不可能做到的,因为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))
请注意,
列表
参数的所有元素都被复制,即返回值与参数没有任何关系(在测试中,假设复制函数
返回一个对象)使用哪个函数复制带填充指针的可调字符串,这样结果也将是可调字符串?我刚刚用copy seq
尝试了你的方法,但它会生成固定大小的数组…@Mark:我认为没有函数可以做到这一点,但你可以使用make array
自己创建一个数组,或者问一个单独的问题。好的,谢谢,现在我知道如何完成我的算法了。它会有点笨重,但现在我知道没有比这更好的了。