我必须结合一个单词列表来产生一个段落。我管理了以下内容:
(define (wordlist2para wl)
(define str " ")
(for ((w wl))
(set! str (string-append str w " ")))
(string-trim str))
(wordlist2para '("this" "is" "a" "test"))
输出:
"this is a test"
它有效,但不起作用。如何为此编写功能代码?
答案 0 :(得分:3)
如果我想明确地做而不使用string-join
,我会递归并使用三种情况:
car
和空格附加到cdr
上的递归。像这样:
(define (wordlist2para ws)
(cond ((null? ws) "")
((null? (cdr ws)) (car ws))
(else (string-append (car ws) " " (wordlist2para (cdr ws))))))
答案 1 :(得分:2)
不需要递归或循环,有原始函数string-join
(参见manual):
(define (wordlist2para wl)
(string-join wl " "))
(wordlist2para '("this" "is" "a" "test"))
;; -> "this is a test"
答案 2 :(得分:2)
我们有标准程序来执行此操作:
;; racket library or srfi/13
(string-join '("this" "is" "it")) ; ==> "this is it"
有一种方法可以始终重写这些非常简单的方法。我想远离球拍的强大功能集,只关注简单的方案和递归程序。请注意,在您的循环中,您正在更改2件事wl
变小,str
变得更长,所以让我们这样做:
; all things that change as arguments
(define (wordlist2para-loop wl str)
(if (null? wl)
str
(wordlist2para-loop (cdr wl)
(string-append str (car wl) " "))))
现在我们只需更换循环:
(define (wordlist2para wl)
(wordlist2para-loop wl ""))
从这里开始,您可以将帮助程序移动到本地或者使其成为命名的let
或任何其他重构,但它实际上并没有真正改变实现的编译结果,只是如何它看起来。
注意我还没有修复只有一个单词的错误。 (wordlist2para '("this")) ; ==> "this "
结果实际上与您的结果完全相同,只是它的尾部递归且功能正常。
答案 3 :(得分:1)
我不确定是否可以调用以下函数,但它确实使用了一些高阶函数:
(define (wordlist2para wl)
(string-trim
(apply string-append
(map (lambda(x) (string-append x " ")) wl))))
(wordlist2para '("this" "is" "a" "test"))
输出:
"this is a test"