繁体   English   中英

Racket - 输出列表的内容

[英]Racket - output content of a list

我已经定义了一个列表(在Racket / Scheme中):

(define myList (cons 'data1 (cons 'data2 (cons 'data3 (cons 'data4 empty)))))

要么

(list 'data1 'data2 'data3 'data4)

我想写一个循环遍历列表并输出列表所有值的函数。

(define (outputListData list)
  (cond 
    [(null? list) list]
    [else (getListData)]))

我可以通过什么功能循环浏览列表的内容? 我知道可以使用firstrest来获取列表数据,但我想这不是正确的方法。

顺便说一句:有没有像php.net这样的好的,紧凑的球拍参考? 我发现官方的Racket文档非常令人困惑......

你可以使用for循环。 例:

(for ([x (list 1 2 3)])
    (printf "~s -> ~s\n" x (* x x)))

当然,有更多功能性方法可以做到这一点,但这种方式也有效。 您可能希望查看如何设计程序的教科书来执行递归方法。 见: http//www.ccs.neu.edu/home/matthias/HtDP2e/

dyoo的解决方案很好,简洁,像Racket一样,内置了有用的迭代例程。但是,仅仅是因为你的'outputListData'并不是标准的递归方式。 你只需要改变几行:

(define (outputListData list)
  (cond 
    [(null? list) #f]             ; actually doesn't really matter what we return
    [else (printf "~s\n" (first list))    ; display the first item ...
          (outputListData (rest list))])) ; and start over with the rest

由于这是一种“命令式”过程,并不是为了返回一个值而设计的,所以只要我们停止重复(避免无限循环),我们对空列表的处理并不重要。 如果列表不为空,我们输出第一个元素,并以列表的其余部分递归开始。

顺便说一下,如果你只需要在其他函数中间使用“for”循环,那么你可以用另一种方式编写几乎相同的东西:

(let loop ((l (list 'foo 'bar 'baz 'quux))) ; or put whatever input you need
   (cond ((null? l) #f)
         (else
           (printf "~s\n" (first l))
           (loop (rest l)))))

考虑这个“命名let”的一种方法是它定义了一个名为loop的临时函数,它就像上面的outputListData一样outputListData Scheme具有很好的属性,它不会像这些那样增加“尾调用”的堆栈,所以你总是可以在这个递归样式中编写forwhile循环的“迭代”。

我强烈推荐Friedman和Felleisen的The Little Schemer快速介绍这种写作风格! 我发现它通过道格拉斯Crockford的页面在这里

根据评论进行编辑:使用 for-each

(for-each display myList)

尝试这个:

(void (map display myList))

打破它:

  • (void x)导致x被忽略,而不是作为值返回到REPL / parent表达式。
  • (map function lst) :对于列表'(a1 a2 ... an)返回列表'((function a1) (function a2) ... (function an))

所以我们使用map来显示所有项目,但由于我们只关心副作用而不是返回值,我们在返回的列表上调用void。

官方文档:

我认为最容易理解的解决方案是提出一个所谓的“列表食者”功能。 这是我的大学在Racket中引入递归和列表的方式。 还有关于Racket的大多数书籍(即“如何设计程序”或“球拍领域”)以这种方式解释它。 这是代码:

(define my-list (list 'data1 'data2 'data3 'data4)) 

(define (print-list a-list-of-data)
  (when (not (empty? a-list-of-data))
    (print (first a-list-of-data))
    (print-list (rest a-list-of-data))))

如果使用示例列表my-list调用该函数,您将获得以下输出:

(print-list my-list)

'data1'data2'data3'data4

该函数执行以下操作:只要给定列表不为空,它就会抓取该列表的第一个元素并将其传递给函数print 然后,它告诉自己与列表的其余部分做同样的事情。 (它在列表的其余部分自称。)第二部分是他们所谓的递归。

但是,您可以使用名为map的函数来缩短它:

(define (print-list a-list-of-data)
  (map print a-list-of-data))

这基本上表示您希望在给定列表的每个元素上调用函数print 输出完全相同。

希望它有所帮助!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM