Глобальные переменные и функции списка - PullRequest
2 голосов
/ 05 ноября 2011

Функция 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. Могу ли я вызвать более 1 функции (или есть обходной путь), например:

    ((append x (car a))
     (manageFirstList (cdr a) b))
    

EDIT: я пытаюсь создать список с первым значением каждого элемента списка test1DataA и вторым значением каждого элемента списка test1DataB, где второе значение элемента списка test1DataA совпадает с первым значением test1DataB его списка элемент. * +1021 *

1 Ответ

2 голосов
/ 06 ноября 2011

О ваших вопросах:

  1. Хотя вы можете обновить глобальную переменную из функции, используя (set! x <value>), вы на самом деле не должны этого делать, это не предпочтительный способ программирования с использованием Scheme; вместо этого вы должны вернуть новый список из вашей процедуры и, если необходимо, присвоить возвращаемое значение x после
  2. Что вы подразумеваете под "правильным путем"? процедура append объединяет два списка, это правильный способ сделать это, если вы спросите меня :). Вы просто называете это так: (append a b), где a и b должны быть списками
  3. Код неправильный, потому что вы окружаете вызов append между дополнительной парой скобок, Схема попытается применить значение, возвращаемое (append ...), как если бы это была процедура с аргументами (manageFirstList (cdr a) b), и, очевидно, он потерпит неудачу, поскольку append возвращает список, а не процедуру. И, возможно, вам следует объяснить, что именно вы имеете в виду под «могу ли я вызвать более 1 функции» - конечно, вы можете, но что вы намерены делать? объединить результаты обоих звонков? обрабатывать результаты самостоятельно?

В любом случае, приведенная выше процедура завершится неудачей по нескольким причинам - вы не учитываете случаи, когда списки являются нулевыми, вы повторяетесь только в одном из списков и т. Д.

Наконец, вы должны уточнить, каков ожидаемый результат процедуры, после вызова с помощью (ff test1DataA test1DataB), какое значение вы хотите видеть в x? напишите это как часть своего вопроса, так как текст "рекурсивно копировать один элемент за раз в глобальный список x" недостаточно ясен.

Edit:

Хорошо, вот мой шанс ответить на ваш вопрос, надеюсь, я вас правильно понял. Обратите внимание, что я использую процедуру 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 внутри процедуры, поскольку в общем случае это не способ Схемы для решения проблем. В итоге значение в x равно:

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