Hi, I'm somewhat new to lisp and I cannot seem to find a function to do
what I would like. I could write one but I think that I must be missing
something. What I want to do is turn a list of numbers into an ascii
key by converting them into single characters with a large radix and
concatenating them together or if my numbers are going to be of too
great a magnitude, into multiple character numbers seporated by some
seporator character such as a dot.
This is what does it for me in elisp:
(defun toakey (val)
(mapconcat (function (lambda (x) (char-to-string (+ 64 x)))) val ""))
When I try to do something similar in clisp I keep getting type errors:
(defun toakey (val)
(concatenate 'string (mapcar 'list (function
(lambda (x) (format "~X" x)))) val))
I have tried it a lot of different ways and still don't seem to
be getting anywhere.
Basically, what I need is some sort of iterative format or print to
string that can take a list of strings or numbers as my argument.
(map 'list #'(lambda (x) (format nil "~X." x)) '(1 35 22 108 37 3))
gives me the numbers in the list converted into strings. Now if I
could just somehow merge them together, I would be set.
Any help would be appreciated,
-Kevin
········@ecst.csuchico.edu
Kevin Haddock <········@ecst.csuchico.edu> writes:
> Basically, what I need is some sort of iterative format or print to
> string that can take a list of strings or numbers as my argument.
(format nil "~{~X~^.~}" '(1 2 10 16 17))
=> "1.2.A.10.11" ;Hex values separated by dots
(format nil "~{~2,'0X~}" '(1 2 10 16 17))
=> "01020A1011" ;Hex values two columns each, padded left wtih 0's
Kevin Haddock <········@ecst.csuchico.edu> writes:
< Basically, what I need is some sort of iterative format or print to
< string that can take a list of strings or numbers as my argument.
(format *terminal-io* "~%~{~X~^.~}"
'(#\1 "35" #b100101 108 #p"/usr/local/lib/" 37 3))
=> 1.35.25.6c./usr/local/lib/.25.3
The ~% is a newline, ~X is base 16, ~{ means do this to the argument
(which is a perfect list) until you get to this ~}. The really useful
~^ says stop here when the last item in the list is reached (prevents
the final `.'). You would almost think format was designed for this
sort of thing - but it always seems like a bad idea to use it for
anything other than output.
I don't believe it is a good idea to use a sequence function on many
different data types at the same time like my example did. I also
wouldn't try to print a pathname as hexidecimal as it doesn't convert
very well.
This will work as well, but map-into is destructive and not as
flexable as the format example.
(let ((l (list 1 35 #\a 108 37 3)))
(coerce (map-into l #'character l) 'string))
=> "^A#al%^C"
also
(nsubstitute #\. #\Space
(write-to-string '(1 35 22 108 37 3) :base 2))
=> "(1.100011.10110.1101100.100101.11)"
Maybe (sxhash "anything") could be useful?
< gives me the numbers in the list converted into strings. Now if I
< could just somehow merge them together, I would be set.
(apply #'concatenate 'string '("1." "23." "16." "6c." "25." "3."))
=> "1.23.16.6c.25.3."
You should check out the function merge, it is very nice; it is
destructive like sort and stable-sort.
Hope this helps some, have fun and enjoy your night.
Kevin Haddock <········@ecst.csuchico.edu> writes:
> (map 'list #'(lambda (x) (format nil "~X." x)) '(1 35 22 108 37 3))
Try
(format nil "~{~X~^.~}" '(1 35 22 108 37 3))
==> ""1.23.16.6c.25.3"
or if you want to have the non-numeric digits in uppercase:
(format nil ···@(~{~X~^.~}~)" '(1 35 22 108 37 3))
==> ""1.23.16.6C.25.3"
For larger radix (up to about 36 on my system) you can substitute ~R
with an appropriate parameter:
(format nil "~{~36R~^.~}" '(1 35 22 108 37 3))
==> "1.z.m.30.11.3"
--
Thomas A. Russ, USC/Information Sciences Institute ···@isi.edu