Как я могу определить, есть ли в списке третий элемент? - PullRequest
5 голосов
/ 20 марта 2009

У меня есть функция, которая принимает список из двух или трех элементов.

;; expecting either ((a b c) d) or ((a b c) d e)
(define (has-third-item ls)
      (if (null? (caddr ls))
          false
          true)
      )

Но этот код не работает с

mcar: expects argument of type <mutable-pair>; given ()

в выражении (null? (Caddr ls)).

Я тоже пробовал

(eq? '() (caddr ls))

но это тоже не сработало. Как мне узнать, есть третий пункт или нет?

Ответы [ 5 ]

9 голосов
/ 20 марта 2009

Вам не нужен caddr, вы хотите (if (null? (Cddr ls)) ... ... Или просто используйте длину, чтобы найти длину списка и сравнить ее со значением, которое вас интересует.

'(), который завершает список, всегда будет в позиции cdr пары, поэтому поиск его в позиции машины (что сделает cad + r) не будет продуктивным.

4 голосов
/ 20 марта 2009

Проблема в том, что если у вас есть список с двумя или менее элементами, вы не можете взять его caddr. Попробуйте это:

(define (has-third-item lst)
  (<= 3 (length lst)))

Могут быть случаи, когда взятие длины списка может быть неэффективным (например, список, содержащий миллионы элементов); в этом случае мы можем проверить, имеет ли список длину ноль, один или два вручную:

(define (has-third-item lst)
  (not (or (null? lst)
           (null? (cdr lst))
           (null? (cddr lst)))))

edit: Относительно двух других ответов, в то время как взятие cddr может работать в этом случае, поскольку входной домен состоит из списка с двумя или тремя elements has-third-item все равно не будет работать для списков с нулем или единицей. В интересах общности, я предлагаю пойти с решением, которое работает для любого домена.

1 голос
/ 06 апреля 2009

Если вы знаете, что в вашем списке есть два или три элемента (как вы говорите), вы можете сделать

(define (has-third-item? l)
  (not (null? (cddr l))))

Вы проверяете, есть ли во второй ячейке против (cddr l) значение cdr или нет. Вам не нужно проверять, имеет ли l значение null или l имеет только один элемент, если только вам не нужна более общая функция.

0 голосов
/ 08 апреля 2009

Почему бы не использовать (третий лс)

Вернет третий элемент или NIL, если его нет.

0 голосов
/ 08 апреля 2009

попробовать ...

(and l (cdr l)(cddr l))
...