I want to convert ("USERID=XYZ" "USERPWD=123")
to "USERID=XYZ&USERPWD=123"
. I tried
(apply #'concatenate 'string '("USERID=XYZ" "USERPWD=123"))
which will return ""USERID=XYZUSERPWD=123"
.
But i do not know how to insert '&'? The following function works but seems a bit complicated.
(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)))))
This solution allows us to use
FORMAT
to produce a string and to have a variable delimiter. The aim is not to cons a new format string for each call of this function. A good Common Lisp compiler also may want to compile a given fixed format string - which is defeated when the format string is constructed at runtime. See the macroformatter
.Explanation:
%d
is just an 'internal' function, which should not be called outsidejoin
. As a marker for that, it has the%
prefix.~/foo/
is a way to call a functionfoo
from a format string.The variables
delim
are declared special, so that there can be a value for the delimiter transferred into the%d
function. Since we can't make Lisp call the%d
function fromFORMAT
with a delimiter argument, we need to get it from somewhere else - here from a dynamic binding introduced by thejoin
function.The only purpose of the function
%d
is to write a delimiter - it ignores the arguments passed byformat
- it only uses thestream
argument.Assuming a list of strings and a single character delimiter, the following should work efficiently for frequent invocation on short lists:
With the newish and simple str library:
It uses format like explained in the other answers:
(author of it, to make simple things like this simple).
A bit late to the party, but
reduce
works fine:Use FORMAT.
~{
and~}
denote iteration,~A
denotes aesthetic printing, and~^
(aka Tilde Circumflex in the docs) denotes printing the , only when something follows it.