2

リストが実際にリストであるかどうかを判断する簡単な方法はありますか?

私の最初の試み:

(defun alistp (list)
    (and (listp list)
         (every (lambda (c)
                    (and (consp c)
                         (or (atom (cdr c))
                             (null (cddr c))))))
                list)))

のTを返します(alistp '((1 . 2) (2 . 3)))

しかし、NILは(alistp '((1 . (4 5 6))))

解決策はありますか?

4

1 に答える 1

6

さて、関連リストの定義を見てみましょう。

アソシエーションリストn。キーと値の関連付けを表すコンスのリスト。各コンの車がキーで、cdrがそのキーに関連付けられた値です。

それを考えると、これは次の実装の可能性がありalistpます。

(defun alistp (alist)
  (and (listp alist)           ; a list
       (every #'consp alist))) ; of conses

さて、あなたのコード例から、おそらくこれを自分で実装できたと思いますが、あなたは別のリストの定義を念頭に置いているようです。あなたが見たリストの例は、多かれ少なかれ次のように見えたと思います:((a . x) (b . y))、多分((a . x) (b . (y z)))しかし、最後の要素としてリストを含む点線のリストは単なるリストであり、あなたの例の入力から、リストを許可したいことは明らかです値として。(とにかく、なぜあなたはそうしませんか?)

あなたが理解しなければならないのは、あなたの入力例((1 . (4 5 6)))はとまったく同じ((1 4 5 6))あるということです。これは、コードで使用される値としてリストを持つリストをほとんど見る方法です。少なくとも、私が通常それらを書く方法です。

さて、あなたも値を除外したいと思うようですnilが、それらもリストです–ただ空の値です()。したがって、実際に念頭に置いている定義は、次のようなものです。

アソシエーションリストn。キーとnil以外の値の関連付けを表す、consセルのリスト。各consのcarがキーで、cdrがそのキーに関連付けられた値です。

それが本当に必要な場合は、新しい定義に従ってください。

(defun alistp (alist)
  (flet ((true-cdr-p (element)
           (and (consp element)        ; cons cell
                (cdr element))))       ; with non-nil cdr (i.e. value) 
    (and (listp alist)                 ; a list
         (every #'true-cdr-p alist)))) ; of cons cells with non-nil cdr

またはそのようなもの。ただし、上記の単純なバージョンを使用することをお勧めします。

于 2013-01-17T05:37:06.473 に答える