unir una tutorial programar programacion palindromo net llamar listas lista lenguaje funcion expresiones español encontrar elemento ejemplos defun compiler compiladores como common aplanar common-lisp

common-lisp - una - programar en common lisp



¿Cuál es la forma canónica de unir cadenas en una lista? (5)

Con la nueva y sencilla librería str :

(ql:quickload "str") (str:join "&" ''("USERID=XYZ" "USERPWD=123"))

Utiliza formato como se explica en las otras respuestas:

(defun join (separator strings) " " (let ((separator (replace-all "~" "~~" separator))) (format nil (concatenate ''string "~{~a~^" separator "~}") strings)))

(Autor de la misma, para hacer cosas simples como esta simple).

Quiero convertir ("USERID=XYZ" "USERPWD=123") a "USERID=XYZ&USERPWD=123" . Lo intenté

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

que devolverá ""USERID=XYZUSERPWD=123" .

Pero no sé cómo insertar ''&''? La siguiente función funciona pero parece un poco complicada.

(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)))))


Esta solución nos permite utilizar FORMAT para producir una cadena y tener un delimitador variable. El objetivo no es considerar una nueva cadena de formato para cada llamada de esta función. Un buen compilador Common Lisp también puede querer compilar una cadena de formato fija dada, que se anula cuando la cadena de formato se construye en tiempo de ejecución. Ver el formatter macros.

(defun %d (stream &rest args) "internal function, writing the dynamic value of the variable DELIM to the output STREAM. To be called from inside JOIN." (declare (ignore args) (special delim)) (princ delim stream)) (defun join (list delim) "creates a string, with the elements of list printed and each element separated by DELIM" (declare (special delim)) (format nil "~{~a~^~/%d/~:*~}" list))

Explicación:

"~{ iteration start ~a print element ~^ exit iteration if no more elements ~/%d/ call function %d with one element ~:* move one element backwards ~}" end of iteration command

%d es solo una función ''interna'', que no debe llamarse una join externa. Como marcador para eso, tiene el prefijo % .

~/foo/ es una forma de llamar a una función foo desde una cadena de formato .

Las variables delim se declaran especiales, de modo que puede haber un valor para el delimitador transferido a la función %d . Como no podemos hacer que Lisp llame a la función %d desde FORMAT con un argumento delimitador, necesitamos obtenerla de otra parte, aquí desde un enlace dinámico introducido por la función join .

El único propósito de la función %d es escribir un delimitador, ya que ignora los argumentos pasados ​​por el format , solo usa el argumento de stream .


Suponiendo una lista de cadenas y un delimitador de un solo carácter, lo siguiente debería funcionar de manera eficiente para la invocación frecuente en listas cortas:

(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)))))


Un poco tarde para la fiesta, pero reduce funciona bien:

(reduce (lambda (acc x) (if (zerop (length acc)) x (concatenate ''string acc "&" x))) (list "name=slappy" "friends=none" "eats=dogpoo") :initial-value "")


Utilice FORMAT .

~{ y ~} denota iteración, ~A denota impresión estética, y ~^ (también conocido como Tilde Circunflejo en los documentos) denota impresión, solo cuando algo lo sigue.

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