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)))]
少了什么?问问警察就知道了