如何在 mapcar 中指定替代参数?
How to specify arguments for substitute in mapcar?
例如,我有一个 "strings" 的列表:("First" "second" "third.").
我需要将所有 "s" 替换为 "a" -> (("Firat")...等
我发现了一个非常漂亮的函数,叫做 substitute,但它只对一个序列有效。
我可以在 mapcar 中使用替代品吗?像这样:
(mapcar 'substitute #\d #\o '(("test") ("wow") ("waow")))
你可以用 LAMBDA
包裹函数:
(mapcar (lambda (string) (substitute #\d #\o string)) '("test" "wow" "waow"))
;=> ("test" "wdw" "wadw")
或者您可以使用名为 CURRY
的辅助函数(它不是 Common Lisp 标准的一部分,但在 Alexandria 中可用)。
(ql:quickload :alexandria)
(use-package :alexandria)
(mapcar (curry #'substitute #\d #\o) '("test" "wow" "waow"))
;=> ("test" "wdw" "wadw")
对于子列表中的多个字符串,可以使用嵌套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."))
内层的 LAMBDA
也可以改成 CURRY
:
(mapcar (lambda (sentence)
(mapcar (curry #'substitute #\d #\o) sentence))
'(("I" "like" "my" "dog.") ("My" "dog" "likes" "me" "too.")))
甚至:
(mapcar (curry #'mapcar (curry #'substitute #\d #\o))
'(("I" "like" "my" "dog.") ("My" "dog" "likes" "me" "too.")))
我在 jkiiski 的非常好的回答中添加了最后一种可能性,在这种情况下为 substitute
指定参数,尽管它可能不是您需要的:
(mapcar #'substitute '(#\x #\x #\x) '(#\a #\b #\c) '("abcd" "abcd" "abcd"))
;; => ("xbcd" "axcd" "abxd")
这里对于每个 i
直到任何传递列表的最小长度,mapcar
传递第一个列表的第 i
个元素作为第一个参数,[=12=第二个的第 ] 个元素作为第二个参数,第 i
个元素作为 substitute
的第三个参数。这是有效的,因为 mapcar
需要一个或任意数量的列表。
只有当您想对(几乎)每个字符串执行不同的替换时,才有意义。
除了平面列表之外,还可以考虑递归,以处理一般的嵌套情况:
(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."))))
例如,我有一个 "strings" 的列表:("First" "second" "third.").
我需要将所有 "s" 替换为 "a" -> (("Firat")...等
我发现了一个非常漂亮的函数,叫做 substitute,但它只对一个序列有效。
我可以在 mapcar 中使用替代品吗?像这样:
(mapcar 'substitute #\d #\o '(("test") ("wow") ("waow")))
你可以用 LAMBDA
包裹函数:
(mapcar (lambda (string) (substitute #\d #\o string)) '("test" "wow" "waow"))
;=> ("test" "wdw" "wadw")
或者您可以使用名为 CURRY
的辅助函数(它不是 Common Lisp 标准的一部分,但在 Alexandria 中可用)。
(ql:quickload :alexandria)
(use-package :alexandria)
(mapcar (curry #'substitute #\d #\o) '("test" "wow" "waow"))
;=> ("test" "wdw" "wadw")
对于子列表中的多个字符串,可以使用嵌套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."))
内层的 LAMBDA
也可以改成 CURRY
:
(mapcar (lambda (sentence)
(mapcar (curry #'substitute #\d #\o) sentence))
'(("I" "like" "my" "dog.") ("My" "dog" "likes" "me" "too.")))
甚至:
(mapcar (curry #'mapcar (curry #'substitute #\d #\o))
'(("I" "like" "my" "dog.") ("My" "dog" "likes" "me" "too.")))
我在 jkiiski 的非常好的回答中添加了最后一种可能性,在这种情况下为 substitute
指定参数,尽管它可能不是您需要的:
(mapcar #'substitute '(#\x #\x #\x) '(#\a #\b #\c) '("abcd" "abcd" "abcd"))
;; => ("xbcd" "axcd" "abxd")
这里对于每个 i
直到任何传递列表的最小长度,mapcar
传递第一个列表的第 i
个元素作为第一个参数,[=12=第二个的第 ] 个元素作为第二个参数,第 i
个元素作为 substitute
的第三个参数。这是有效的,因为 mapcar
需要一个或任意数量的列表。
只有当您想对(几乎)每个字符串执行不同的替换时,才有意义。
除了平面列表之外,还可以考虑递归,以处理一般的嵌套情况:
(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."))))