(defun mockify (chars)
(let ((lst (coerce chars 'list)))
(if (equal lst nil)
nil
(coerce
(cons (cons (char-upcase (car lst))
(char-downcase (cadr lst)))
(mockify (cddr lst)))
'string))))
你的表达式类型令人困惑,在使用SBCL时会导致错误:
> (mockify "meow")
The value
(#\O . #\w)
is not of type
CHARACTER
when setting an element of (ARRAY CHARACTER)
[Condition of type TYPE-ERROR]
另外,在你的代码中,你需要处理一些特殊情况,因为在现有情况下,可能会调用只有一个元素的列表上的 (cadr list)
,即 (second list)
。这时,结果将为 NIL
并且 char-downcase
将因错误而失败。
仅使用字符串
我建议编写一个不使用中间列表的函数版本:
- 令 R 为整个字符串的
string-downcase
- 然后修改 R 的每隔一个字符并将其大写
例如,实现它的一种方式 (还有其他的):
(defun mockify (chars)
(let ((chars (string-downcase chars)))
(prog1 chars
(upcasify chars 0))))
(defun upcasify (string index)
(when (< index (length string))
(setf (char string index) (char-upcase (char string index)))
(upcasify string (+ index 2))))
仅使用列表
如果您更喜欢使用递归函数来处理列表,我会更愿意分层定义它:
- 将字符串转换为列表
- 递归地处理列表
- 最后将结果列表转回字符串
这样可以避免在每个步骤中进行字符串到列表的转换,并使代码在每个级别上更简单。
(defun mockify (chars)
(coerce (mockify-list (coerce chars 'list)) 'string))
(defun mockify-list (chars)
...)
列表版本是递归的,看起来与您尝试的操作类似,但要注意边角情况。