2012-01-12 52 views
20

我想將("USERID=XYZ" "USERPWD=123")轉換爲"USERID=XYZ&USERPWD=123"。我試過在列表中連接字符串的規範方式是什麼?

(apply #'concatenate 'string '("USERID=XYZ" "USERPWD=123")) 

這將返回""USERID=XYZUSERPWD=123"

但我不知道如何插入'&'?以下功能起作用,但似乎有點複雜。

(defun join (list &optional (delim "&")) 
    (with-output-to-string (s) 
     (when list 
      (format s "~A" (first list)) 
      (dolist (element (rest list)) 
       (format s "~A~A" delim element))))) 

回答

37

使用FORMAT

~{~}分別表示迭代,~A表示審美印刷和~^(又名代字號抑揚在docs)表示打印的東西如下它只有當。

* (format nil "~{~A~^, ~}" '(1 2 3 4)) 

"1, 2, 3, 4" 
* 
+0

不知道〜^;太好了! – 2012-01-12 18:42:37

+0

這不幸在Emacs「elisp」中不起作用。他們有不同的格式功能。在Emacs中有沒有類似的方法可以做到這一點? – killdash9 2013-10-25 23:18:20

+0

@russ:可能。不是elisp嚮導,我回到了基本的Lisp ...'(defun join-to-str(東西和其他字符串) (標籤 ((recurser(字符串) (cond((>(length strings)1) (追加(名單(車字符串) 東西) (recurser(CDR字符串)))) (T (缺點(車字符串)無))))) (申請「CONCAT(recurser字符串)))) ' – 2013-10-26 20:47:17

1

假設字符串列表和單個字符分隔符,下面應該提高工作效率頻繁調用的短名單:

(defun join (list &optional (delimiter #\&)) 
    (with-output-to-string (stream) 
    (join-to-stream stream list delimiter))) 

(defun join-to-stream (stream list &optional (delimiter #\&)) 
    (destructuring-bind (&optional first &rest rest) list 
    (when first 
     (write-string first stream) 
     (when rest 
     (write-char delimiter stream) 
     (join-to-stream stream rest delimiter))))) 
0

有點遲到了,但reduce正常工作:

(reduce (lambda (acc x) 
      (if (zerop (length acc)) 
       x 
       (concatenate 'string acc "&" x))) 
     (list "name=slappy" "friends=none" "eats=dogpoo") 
     :initial-value "") 
0
(defun %d (stream &rest args) 
    (declare (ignore args) 
      (special delim)) 
    (princ delim stream)) 

(defun join (list delim) 
    (declare (special delim)) 
    (format nil "~{~a~^~/%d/~:*~}" list)) 
相關問題