Reputation: 703
For example, I have a list of "strings" : ("First" "second" "third.").
And I need to replace all "s" to "a" -> (("Firat")...etc
I've found very beautiful function called substitute, but it works only for one sequence.
Can I use substitute in mapcar ? Something like this:
(mapcar 'substitute #\d #\o '(("test") ("wow") ("waow")))
Upvotes: 2
Views: 495
Reputation: 1064
Beyond a flat list one could consider recursion, to handle the general nesting case:
(labels ((my-sub (s)
(typecase s
(string (substitute #\d #\o s))
(list (mapcar #'my-sub s))
(otherwise s))))
(my-sub '(("I" "like" "my" "dog.")
("My" ("dog" "likes" "me") "too."))))
Upvotes: 2
Reputation: 16156
I'm adding to jkiiski's very nice answer one final possibility to specify arguments to substitute
in this case, though it's probably not what you need:
(mapcar #'substitute '(#\x #\x #\x) '(#\a #\b #\c) '("abcd" "abcd" "abcd"))
;; => ("xbcd" "axcd" "abxd")
Here for every i
up to the lowest length of any passed list, mapcar
passes the i
th element of the first list as first argument, the i
th element of the second as second argument and the i
th element as third argument to substitute
. This works because mapcar
takes one or any number of lists.
Using this only makes sense if you want to perform different substitutions on (almost) each of the strings.
Upvotes: 3
Reputation: 8411
You can wrap a LAMBDA
around the function:
(mapcar (lambda (string) (substitute #\d #\o string)) '("test" "wow" "waow"))
;=> ("test" "wdw" "wadw")
Or you can use a helper function called CURRY
(which is not part of the Common Lisp standard, but is available in Alexandria for example).
(ql:quickload :alexandria)
(use-package :alexandria)
(mapcar (curry #'substitute #\d #\o) '("test" "wow" "waow"))
;=> ("test" "wdw" "wadw")
For multiple strings in sublists, you can use nested mapcar/lambda:
(mapcar (lambda (sentence)
(mapcar (lambda (string)
(substitute #\d #\o string))
sentence))
'(("I" "like" "my" "dog.") ("My" "dog" "likes" "me" "too.")))
;=> (("I" "like" "my" "ddg.") ("My" "ddg" "likes" "me" "tdd."))
The inner LAMBDA
could be changed to a CURRY
too:
(mapcar (lambda (sentence)
(mapcar (curry #'substitute #\d #\o) sentence))
'(("I" "like" "my" "dog.") ("My" "dog" "likes" "me" "too.")))
Or even:
(mapcar (curry #'mapcar (curry #'substitute #\d #\o))
'(("I" "like" "my" "dog.") ("My" "dog" "likes" "me" "too.")))
Upvotes: 5