Reputation: 1164
I'd like to turn String into lists. For example, http => (h t t p).
I try:
(defun string-to-list (s)
(assert (stringp s) (s) "~s :questa non e una stringa")
(coerce s 'list))
but if I do
(string-to-list "http")
results:
(#\h #\t #\t #\p).
Can I remove #\ ? thanks in advance :)
Upvotes: 8
Views: 7622
Reputation: 139251
Why would you do that? What you ask is to split a string (a one-dimensional array of characters) into a list of symbols. Do you really want that?
#\h
is a character object printed.
You can print them differently:
CL-USER 8 > (princ #\h)
h
CL-USER 9 > (prin1 #\h)
#\h
Let's print the list using PRINC
:
CL-USER 10 > (map nil #'princ (coerce "Hello!" 'list))
Hello!
Btw., since strings, vectors and lists are sequences, you can MAP directly over the string...
CL-USER 11 > (map nil #'princ "Hello!")
Hello!
Upvotes: 20
Reputation: 139251
You can print characters unescaped. See the variable *PRINT-ESCAPE*
.
The function WRITE
has a keyword parameter :ESCAPE
for that:
(defun string-to-list (s)
(assert (stringp s) (s) "~s :questa non e una stringa")
(write (coerce s 'list) :escape nil)
CL-USER 11 > (string-to-list "abcd")
(a b c d)
(#\a #\b #\c #\d)
In above example the first form is printed by calling WRITE
and the second form is the return value printed by the REPL.
Upvotes: 3
Reputation: 6681
Expanding upon larsmans' answer, you can print lowercase symbols unquoted if you change the readtable:
(let ((*readtable* (copy-readtable)))
(setf (readtable-case *readtable*) :preserve)
(prin1 (loop for c in (coerce "http" 'list)
collecting (intern (string c)))))
This will print (h t t p)
and return (|h| |t| |t| |p|)
.
Upvotes: 3
Reputation: 363517
You can turn a string into a symbol with intern
. You can turn a character into a string with string
. Interning a lower-case string might cause it to be printed as |h|
instead of h
, so you'll want to string-upcase
it. Putting all that together gives:
(loop for c in (coerce "http" 'list)
collecting (intern (string-upcase (string c))))
Upvotes: 3