Поиск элемента в списке в схеме - PullRequest
1 голос
/ 20 мая 2011

Я очень новичок в Схеме и пытаюсь понять, как она работает;поэтому я хочу написать базовый код: во-первых, у меня есть набор определений: почтовый индекс (ZIPCODE CITY STATE)

(define zipcodes '(
 (96774 ookala hawaii)
 (90001 losangeles california)
 (90263 malibu california)
 (10044 newyork newyork)
 ))

я пытаюсь написать функцию, в которой вводится почтовый индекс инапример, вернуть город и название штата:

 >(find '10044)
 (list 'newyork 'newyork)

 >(find '99999)
 empty because there is not zipcode like that.

Большое спасибо ...

Мне не разрешено использовать функцию LET

Ответы [ 3 ]

6 голосов
/ 20 мая 2011

Использование assoc

> (assoc 90001 zipcodes)
(90001 losangeles california)
> (cdr (assoc 90001 zipcodes))
(losangeles california)
2 голосов
/ 20 мая 2011
(define filter
   (lambda (proc lst)
       (cond ((null? lst) '())
             ((proc (car lst)) (cons (car lst) (filter proc (cdr lst))))
             (else
                (filter proc (cdr lst))))))

(define find-zip
   (lambda (zip lst)
      (define match (filter (lambda (item) (= zip (car item))) lst))
      (if (null? match)
          '()
          (cdar match))))

(define (find zip)
    (find-zip zip zipcode))

Я думаю, что это будет работать для вас. Фильтр будет применять свой первый аргумент (процедуру) к каждому элементу в своем втором аргументе, который должен быть списком. Первый аргумент должен возвращать логическое значение для каждого передаваемого элемента. Затем фильтр вернет список со всеми элементами, которые вернули true, когда был применен первый аргумент. В противном случае возвращается пустой список.

В этом случае каждый элемент в списке, который вы передаете, сам является списком из 3 элементов, поэтому он сравнивает первый элемент в этом списке с искомым почтовым индексом. Если это совпадение, оно возвращает true. Поэтому, если почтовый индекс находится в списке, он вернет подсписок из трех элементов. Затем мы проверяем, получили ли мы пустой список, и если да, то мы возвращаем пустой список. В противном случае мы берем CDR автомобиля, чтобы получить желаемый город и штат.

1 голос
/ 20 мая 2011

Ну, так что вы можете просто фильтровать список по почтовому индексу, я набросал некоторый код ниже (я бы написал по-другому, за исключением того, что я не знаю, что у вас есть за пределами того, что определено в RnRS).

(define find-zip
  (lambda (zip codelist)
   (if (empty? codelist) empty
    (if (= zip (car (car codelist)) (list (cadr (car codelist)) (caddr (car codelist)))
        (find-zip zip (cdr codelist))))))

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

...