全局变量和列表函数

时间:2011-11-05 02:29:43

标签: scheme racket

函数manageFirstList应该递归地将一个元素复制到全局列表x。

(define test1DataA '(("a" "a") ("b" "b") ("c" "c") ("d" "d") ("e" "ok")))
(define test1DataB '(("a" "aa") ("b" "bb") ("c" "cc") ("d" "dd") ("ok" "Ir OK!")))

(define x '())

(define manageFirstList
  (lambda (a b)  
    ((cond ((not (null? b))
            ((append x (car a))
             (manageFirstList (cdr a) b)))))))

(define ff (lambda (a b) (manageFirstList a b)))

(ff test1DataA test1DataB)

但它会导致错误:

car: expects argument of type <pair>; given '()

问题是:

  1. 如何更新全局值`x'?
  2. 如何以正确的方式连接列表?
  3. 我是否可以调用多个功能(或有解决方法),如下所示:

    ((append x (car a))
     (manageFirstList (cdr a) b))
    
  4. 编辑:我要做的是创建一个列表,其中包含每个test1DataA列表项的第一个值和每个test1DataB列表项的第二个值,其中test1DataA列表元素第二个值与test1DataB列表中的第一个值相同元件。

1 个答案:

答案 0 :(得分:2)

关于您的问题:

  1. 虽然可以使用(set! x <value>)从函数中更新全局变量,但你真的不应该,这不是使用Scheme编程的首选方式;相反,您应该从过程中返回一个新列表,如有必要,之后将返回的值分配给x
  2. “正确的方式”是什么意思? append程序连接两个列表,这是正确的方法,如果你问我:)。您只需将其称为:(append a b),其中ab 必须为列表
  3. 代码是错误的,因为你在一对额外的括号之间围绕对append的调用,Scheme将尝试应用(append ...)返回的值,就好像它是一个带参数的过程(manageFirstList (cdr a) b),显然它会失败,因为append返回一个列表,而不是一个过程。也许你应该准确解释你的意思是什么?“我可以调用超过1个功能” - 当然你可以,但你打算做什么?结合两个电话的结果?独立处理结果?
  4. 无论如何,上面的过程会因为几个原因而失败 - 你没有考虑列表为空的情况,你只是在其中一个列表上重复出现等等。

    最后,在使用(ff test1DataA test1DataB)调用后,您应该明确该程序的预期结果是什么,您希望在x中看到什么值?把它写成你问题的一部分,因为文本“递归地将一个元素复制到全局列表x”还不够清楚。

    修改

    好的,这是我回答你的问题,我希望我能正确理解你。请注意,我正在使用assoc过程搜索第一个列表中的每个第二个值,在第二个列表中,因此将第二个列表解释为关联列表:

    (define (manageFirstList lst1 lst2)
      (cond ((null? lst1) '())
            (else (cons (list (caar lst1) (cadr (assoc (cadar lst1) lst2)))
                        (manageFirstList (cdr lst1) lst2)))))
    

    现在,如果您绝对需要更改x全局变量的值,只需执行以下操作:

    (define x '())
    (set! x (manageFirstList test1DataA test1DataB))
    

    注意我是如何完全避免在程序中修改x的,因为一般来说,这不是解决问题的Scheme方法。最后,x中的值为:

    (("a" "aa") ("b" "bb") ("c" "cc") ("d" "dd") ("e" "Ir OK!"))