List 方案中的循环函数
关于循环的问题 用列表做这件事总是让我困惑。你会怎么做这样的事List 方案中的循环函数,list,loops,scheme,racket,List,Loops,Scheme,Racket,关于循环的问题 用列表做这件事总是让我困惑。你会怎么做这样的事 (define-struct song (title artist length)) (define song1 (make-song "Hey, Jude" "The Beatles" 431)) (define songs (list song (make-song "Sing" "JB" 200) (make-song "Yell" "LS" 188))) (check-expect (count song
(define-struct song (title artist length))
(define song1 (make-song "Hey, Jude" "The Beatles" 431))
(define songs (list song
(make-song "Sing" "JB" 200)
(make-song "Yell" "LS" 188)))
(check-expect (count songs) 819)
计算所有歌曲的长度
(define (count n)
(cond
[(empty? n) 0]
[else
(first n)
(count (rest n)))
你觉得这个怎么样?有了结构,你可以简单地把它们拆开
(+(歌曲长度).
不确定如何在列表中继续。例如,我不确定歌曲1
或歌曲列表中的第一个和其余是什么。歌曲列表中的每个元素都是一首歌曲。给定这样的列表歌曲,(汽车歌曲)
是列表中的第一个元素。(歌曲长度(汽车歌曲))
返回列表中第一首歌曲的长度。看起来您正在尝试对所有歌曲的长度求和。习惯用法可能大致如下:
(define (sum-lengths songs)
(let sl ((songs songs)
(sum 0))
(if (null? songs) sum
(sl (cdr songs) (+ sum (song-length (car songs)))))))
这个模式实际上只是计算一个折叠
(defun (sum-lengths songs)
(foldl 0 (lambda (song sum) (+ sum (song-length song))) songs))
就个人而言,我认为编写lambda
函数只是将歌曲长度
应用于每首歌曲有点笨拙。您也可以这样做
(foldl 0 + (map song-length songs))
但这将构建一个中间列表来保存歌曲长度。我更喜欢Common Lisp的reduce
,其中您可以指定一个键
函数,该函数应用于列表的每个元素,您可以使用该函数编写:
(reduce '+ songs :key 'song-length)
歌曲列表中的每个元素都是一首歌曲。给定这样一个列表歌曲
,(汽车歌曲)
是列表中的第一个元素。(歌曲长度(汽车歌曲))
返回列表中第一首歌曲的长度。看起来您试图将所有歌曲的长度相加。按照习惯用法,它可能大致如下所示:
(define (sum-lengths songs)
(let sl ((songs songs)
(sum 0))
(if (null? songs) sum
(sl (cdr songs) (+ sum (song-length (car songs)))))))
这个模式实际上只是计算一个折叠
(defun (sum-lengths songs)
(foldl 0 (lambda (song sum) (+ sum (song-length song))) songs))
就个人而言,我认为编写lambda
函数只是将歌曲长度
应用于每首歌曲有点笨拙。您也可以这样做
(foldl 0 + (map song-length songs))
但这将构建一个中间列表来保存歌曲长度。我更喜欢Common Lisp的reduce
,其中您可以指定一个键
函数,该函数应用于列表的每个元素,您可以使用该函数编写:
(reduce '+ songs :key 'song-length)
歌曲列表中的每个元素都是一首歌曲。给定这样一个列表歌曲
,(汽车歌曲)
是列表中的第一个元素。(歌曲长度(汽车歌曲))
返回列表中第一首歌曲的长度。看起来您试图将所有歌曲的长度相加。按照习惯用法,它可能大致如下所示:
(define (sum-lengths songs)
(let sl ((songs songs)
(sum 0))
(if (null? songs) sum
(sl (cdr songs) (+ sum (song-length (car songs)))))))
这个模式实际上只是计算一个折叠
(defun (sum-lengths songs)
(foldl 0 (lambda (song sum) (+ sum (song-length song))) songs))
就个人而言,我认为编写lambda
函数只是将歌曲长度
应用于每首歌曲有点笨拙。您也可以这样做
(foldl 0 + (map song-length songs))
但这将构建一个中间列表来保存歌曲长度。我更喜欢Common Lisp的reduce
,其中您可以指定一个键
函数,该函数应用于列表的每个元素,您可以使用该函数编写:
(reduce '+ songs :key 'song-length)
歌曲列表中的每个元素都是一首歌曲。给定这样一个列表歌曲
,(汽车歌曲)
是列表中的第一个元素。(歌曲长度(汽车歌曲))
返回列表中第一首歌曲的长度。看起来您试图将所有歌曲的长度相加。按照习惯用法,它可能大致如下所示:
(define (sum-lengths songs)
(let sl ((songs songs)
(sum 0))
(if (null? songs) sum
(sl (cdr songs) (+ sum (song-length (car songs)))))))
这个模式实际上只是计算一个折叠
(defun (sum-lengths songs)
(foldl 0 (lambda (song sum) (+ sum (song-length song))) songs))
就个人而言,我认为编写lambda
函数只是将歌曲长度
应用于每首歌曲有点笨拙。您也可以这样做
(foldl 0 + (map song-length songs))
但这将构建一个中间列表来保存歌曲长度。我更喜欢Common Lisp的reduce
,其中您可以指定一个键
函数,该函数应用于列表的每个元素,您可以使用该函数编写:
(reduce '+ songs :key 'song-length)
这一个很简单,所以我不会破坏它的乐趣。事实上,你几乎成功了!使用此模板:
(define (count n)
(cond
[(empty? n) 0]
[else
(+ <???>
(count (rest n)))]))
(定义(计数n)
(续)
[(空?n)0]
[其他
(+
(计数(其余n)))]
缺少什么?只需询问列表中当前歌曲(第一首歌曲)的长度。递归将负责添加所有歌曲
它与您迭代任何其他列表时使用的模板相同:
- 询问列表是否为空,并返回适合此情况的值。因为我们正在添加数字,返回
0
很好,它将很好地结束递归
- 如果列表非空,只需从第一个元素(本例中为歌曲的长度)中获取感兴趣的值,将其与递归调用(使用
+
,因为我们正在添加数字)相结合,并推进递归以处理列表的其余部分
这一个很简单,所以我不会破坏它的乐趣。事实上,你几乎成功了!使用此模板:
(define (count n)
(cond
[(empty? n) 0]
[else
(+ <???>
(count (rest n)))]))
(定义(计数n)
(续)
[(空?n)0]
[其他
(+
(计数(其余n)))]
缺少什么?只需询问列表中当前歌曲(第一首歌曲)的长度。递归将负责添加所有歌曲
它与您迭代任何其他列表时使用的模板相同:
- 询问列表是否为空,并返回适合此情况的值。因为我们正在添加数字,返回
0
很好,它将很好地结束递归
- 如果列表非空,只需从第一个元素(本例中为歌曲的长度)中获取感兴趣的值,将其与递归调用(使用
+
,因为我们正在添加数字)相结合,并推进递归以处理列表的其余部分
这一个很简单,所以我不会破坏它的乐趣。事实上,你几乎成功了!使用此模板:
(define (count n)
(cond
[(empty? n) 0]
[else
(+ <???>
(count (rest n)))]))
(定义(计数n)
(续)
[(空?n)0]
[其他
(+
(计数(其余n)))]
少了什么?问问警察就知道了