2016-09-02 46 views
1

我必须合并单词列表才能生成段落。我管理的以下内容:将单词列表结合到Racket中的一个段落

(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" 

它的工作原理,但它不是功能。我如何为此编写功能代码?

回答

3

如果我想明确地做到这一点,而不是使用string-join,我会重复并用三例:

  • 空列表产生空字符串
  • 一个元素列表产生其鞋底元件(这避免了拖尾separa tor)
  • 否则,在cdr上附加car和一个空间到递归。

像这样:

(define (wordlist2para ws) 
    (cond ((null? ws) "") 
     ((null? (cdr ws)) (car ws)) 
     (else (string-append (car ws) " " (wordlist2para (cdr ws)))))) 
+0

功能好的编码。 – rnso

2

无需递归或循环的,有这种情况的原始功能string-join(见manual):

(define (wordlist2para wl) 
    (string-join wl " ")) 

(wordlist2para '("this" "is" "a" "test")) 

;; -> "this is a test" 
+0

多么容易!谢谢。 – rnso

2

我们必须做这个标准程序:

;; racket library or srfi/13 
(string-join '("this" "is" "it")) ; ==> "this is it" 

有一种方法总是重写这些是相当简单。我想摆脱球拍出色的功能集,并且只关注简单的递归程序。请注意,在你的循环,你正在改变两件事情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 "结果实际上与您的完全相同,只是它的尾递归和功能。

+0

很好的解释。 – rnso

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" 
相关问题