[英]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)]))
我可以通过什么功能循环浏览列表的内容? 我知道可以使用first
& rest
来获取列表数据,但我想这不是正确的方法。
顺便说一句:有没有像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具有很好的属性,它不会像这些那样增加“尾调用”的堆栈,所以你总是可以在这个递归样式中编写for
或while
循环的“迭代”。
我强烈推荐Friedman和Felleisen的The Little Schemer快速介绍这种写作风格! 我发现它通过道格拉斯Crockford的页面在这里 。
我认为最容易理解的解决方案是提出一个所谓的“列表食者”功能。 这是我的大学在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.