0

シンボル/トークンとリストが渡される関数を作成しようとしています

関数は、リストにシンボル/トークンが含まれているかどうかを確認します。そうであれば対応するキーペアを返し、そうでなければnulを返します

私はdefparameterを作りました:

(defparameter *pairs* 
  '((apple green)
    (banana yellow)
    (grape purple)))

次に、タスクを実行する関数を作成しました:

(defun list-pairs (word list)
  (if (eq word list)
    (rest(list)))
  nil))

そのように実行されたときの関数:(list-pairs '(banana) *pairs*)私はnulを取得し続けます

返してほしいのは黄色、つまりキーペアです

誰かが間違っていることを説明するのを手伝ってくれませんか。私はLISPに非常に慣れていません

4

4 に答える 4

4
(second (assoc 'banana *pairs*))

与える

YELLOW

編集: 以下の Joshua Taylor のコメントを参照してassoc、関連リスト (または短い: alists ) のドキュメントと概念について説明します (非常に簡単に: alistscarは、各コンスのコンス セルのリストによって形成されるキー値データ構造です)。cell がキーで、cdrが値です)。

独自のコードの問題点について:

ifyour :の条件では、引数が引数と同じ(eq word list)かどうかをテストしています。しかし、実際には内を探したいので、それは正しい条件ではありません。wordlistwordlist

また、条件が真だったとしても、評価しているのは です(rest(list))listこれは、引数の残りの部分ではなく、関数を呼び出すことによって作成された新しい空のリストの残りの部分ですlist

そして最後に、3 番目の閉じ括弧でif式を閉じています。そのため、他のすべてが正しい場合でも(rest(list))、 finalは関数の戻り値になります。を式の括弧にnil移動して、else-consequent にし、式の値を関数の戻り値にする必要があります。nilifif

于 2013-10-21T21:05:22.300 に答える
1

別の方法として:

(defun list-pairs (word list)
  (dolist (p list)
    (if (eq word (first p))
      (return (second p)))))

(defparameter *pairs* 
  '((apple green)
    (banana yellow)
    (grape purple)))

(list-pairs 'banana *pairs*)
YELLOW
于 2013-10-21T21:11:32.157 に答える
1

あなたが探しているのは

(defun list-pairs (word list)
  (if list
    (if (eq (caar list) word)
      (cadar list)
      (list-pairs word (cdr list))))))

または、小さな最適化として let を使用します。

(defun list-pairs (word list)
  (if list
    (let ((c (car list)))
      (if (eq (car c) word)
        (cadr c)
        (list-pairs word (cdr list))))))

これは、末尾呼び出しの最適化を行う Common Lisp 実装でうまく機能します。あなたはそれを次のように使うべきです

(list-pairs 'banana *pairs*)

しかし、Common Lisp では loop マクロが一般的に好まれます:

(defun list-pairs (word list)
  (loop for c in list
    when (eq (car c) word)
    return (cadr c)))
于 2013-10-21T21:00:01.110 に答える
0

あなたの仕事は私にいくつかの疑問を残しています。

1.) 関数はシンボルを取得する必要があります。しかし、なぜこのように呼ぶのですか: (list-pairs '(banana) *pairs*)? (list-pairs 'banana *pairs*)十分ではないでしょうか?

2.) ペアの最初の要素の一致のみを取得しますか? つまり、シンボルbananaとに対して同じ結果が必要yellowですか?

最初の要素だけを検索したい場合は、Rörd がすでに言及しているassocので、完璧です。ペアの両方の要素を確認したい場合はremove-if-not、試してみてください。

(defun list-pairs (word list)
  (remove-if-not
   #'(lambda (sublist) (member word sublist))
   list))
于 2013-10-21T21:41:44.357 に答える