对多个字符串进行操作以生成一个字符串
Operating on multiple strings to produce a string
将 result
设置为 ("cypueihajytotrdkgzxfqplbwn" . "cypueihajytomrdkgzxfqplbwn")
,下面的代码给出了删除不匹配字符 "t" 的预期结果:
"cypueihajytordkgzxfqplbwn"
如果没有 concat
,结果将作为整数列表返回,表示字符串中每个字符的 ASCII 值。但是输入本身被评估者视为字符串。所以我在算法中失去了 result
的字符串性(可能是因为 mapcar*
将每个字符串视为字符列表,而字符只是整数)。
我的问题是 - 是否有一种惯用的方法来保持变量的严格性,而不是必须在最后使用 concat
或 apply #'string
重新强制执行它。恕我直言,concat
使代码有点嘈杂(呃)。
(print (concat (mapcar #'car (cl-remove-if-not
(lambda (r) (equal (car r) (cdr r)))
(mapcar* #'cons (car result) (cdr result))))))
Emacs Lisp 中的主要数据类型是列表。 Emacs 提供了很多函数(如car
和cdr
)来处理列表,列表比数组(包括向量和字符串)更容易处理。例如,函数 mapcar
returns 即使您将字符串或向量传递给它也是一个列表:
(mapcar #'identity "hello")
;; => (104 101 108 108 111)
(mapcar #'identity [1 2 3])
;; => (1 2 3)
将数组转换为列表、处理列表,然后再转换回数组的情况并不少见。除了 concat
和 string
,您还可以使用 mapconcat
.
构建字符串
对于你的代码,你使用了3次类似mapcar的函数,下面只使用了一次,我觉得这样更容易阅读
(let ((result (cons "cypueihajytotrdkgzxfqplbwn"
"cypueihajytomrdkgzxfqplbwn")))
(concat
(delq
nil
(cl-mapcar
(lambda (c1 c2) (and (= c1 c2) c1))
(car result) (cdr result)))))
;; => "cypueihajytordkgzxfqplbwn"
使用命令式方法,代码更加简洁
(let ((result (cons "cypueihajytotrdkgzxfqplbwn"
"cypueihajytomrdkgzxfqplbwn")))
(cl-loop for x across (car result)
for y across (cdr result)
when (= x y)
concat (string x)))
;; => "cypueihajytordkgzxfqplbwn"
将 result
设置为 ("cypueihajytotrdkgzxfqplbwn" . "cypueihajytomrdkgzxfqplbwn")
,下面的代码给出了删除不匹配字符 "t" 的预期结果:
"cypueihajytordkgzxfqplbwn"
如果没有 concat
,结果将作为整数列表返回,表示字符串中每个字符的 ASCII 值。但是输入本身被评估者视为字符串。所以我在算法中失去了 result
的字符串性(可能是因为 mapcar*
将每个字符串视为字符列表,而字符只是整数)。
我的问题是 - 是否有一种惯用的方法来保持变量的严格性,而不是必须在最后使用 concat
或 apply #'string
重新强制执行它。恕我直言,concat
使代码有点嘈杂(呃)。
(print (concat (mapcar #'car (cl-remove-if-not
(lambda (r) (equal (car r) (cdr r)))
(mapcar* #'cons (car result) (cdr result))))))
Emacs Lisp 中的主要数据类型是列表。 Emacs 提供了很多函数(如car
和cdr
)来处理列表,列表比数组(包括向量和字符串)更容易处理。例如,函数 mapcar
returns 即使您将字符串或向量传递给它也是一个列表:
(mapcar #'identity "hello")
;; => (104 101 108 108 111)
(mapcar #'identity [1 2 3])
;; => (1 2 3)
将数组转换为列表、处理列表,然后再转换回数组的情况并不少见。除了 concat
和 string
,您还可以使用 mapconcat
.
对于你的代码,你使用了3次类似mapcar的函数,下面只使用了一次,我觉得这样更容易阅读
(let ((result (cons "cypueihajytotrdkgzxfqplbwn"
"cypueihajytomrdkgzxfqplbwn")))
(concat
(delq
nil
(cl-mapcar
(lambda (c1 c2) (and (= c1 c2) c1))
(car result) (cdr result)))))
;; => "cypueihajytordkgzxfqplbwn"
使用命令式方法,代码更加简洁
(let ((result (cons "cypueihajytotrdkgzxfqplbwn"
"cypueihajytomrdkgzxfqplbwn")))
(cl-loop for x across (car result)
for y across (cdr result)
when (= x y)
concat (string x)))
;; => "cypueihajytordkgzxfqplbwn"