2014-07-23 55 views
2

列表的重複元素我需要重複列表中的每個元素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 

這不是我想要的。

所以我的問題是:如何以最習慣的方式解決問題,以便結果列表的每個元素都會被引用,以複製單獨的對象。

回答

7

這是不可能的,因爲Common Lisp不提供通用的複製功能。此外,

  • 一些對象是直接(如fixnum),並不能在任何意義上被複制
  • 某些對象immutable並複製它們是一種浪費
  • 一些對象嵌套,你將不得不決定是否要deep or shallow copy

然而,如果你已經解決了這個問題,並提供複印功能,這是不是太辛苦:

​​

注意所有list參數的元素被複制,也就是,返回值沒有intersection與參數(eq測試下並且假設copy-function返回fresh對象)

+0

隨着其函數我複製一個可調整的字符串與填充指針,以便結果也可以調整字符串?我只是用'copy-seq'嘗試了你的方法,但是它產生了固定大小的數組... ... – Mark

+1

@Mark:我不認爲有這樣做的函數,但你可以用'make - 陣列「 - 或者只是問一個單獨的問題。 – sds

+0

好的,謝謝,現在我知道如何完成我的算法。這會有點笨重,但現在我知道沒有比這更好的了。 – Mark