2012-01-12 8 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は何かがそれを次のときにのみ、印刷表し美的印刷、および~^(ドキュメントで別名チルダ曲折)です。

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

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

〜^については分かりませんでした。いいよ! –

+0

これは残念ながら、Emacs "elisp"では動作しません。彼らは異なるフォーマット機能を持っています。 Emacsでこれを行うには匹敵する方法はありますか? – killdash9

+0

@russ:おそらく。 elispの魔法使いではないので、私は基本的なLispに戻りました。 "(defun join-to-str(thing&rest strings) (ラベル (recurser(strings) (cond((>(length strings)1) ((リスト(車の列) ものを追加) (再帰関数(CDR文字列)))) (トン (短所(車の列)はnil))))) ()「CONCAT(再帰関数の文字列)を適用)) ' –

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)) 
関連する問題