2010-11-11 3 views
13

ich „Land der Lisp“ Lesen (die übrigens ist, einer der besten technischen Bücher, die ich je gelesen habe) und ich komme über AssoziationslisteGrund Frage zu Zuordnungsliste in Lisp

(defparameter *edges* 
    '((living-room (garden west door) 
        (attic upstairs ladder)) 
     (garden (living-room east door)) 
     (attic (living-room downstairs ladder)))) 

Erstens, ist die Assoziationsliste in Lisp das gleiche Konzept der Java-Map (Schlüssel-Wert-Bindung)?
Für Wohnzimmerschlüssel, wie ist es möglich, mehr als einen Wert zu haben? warum nicht den Wert mit einer Liste einzuschließen:

(living-room ((garden west door) (attic upstairs ladder))) 

Antwort

13
  1. Ja, die Zuordnungsliste ein Weg ist, Schlüssel-Wert-Assoziationen zum Ausdruck bringen. Andere Strukturen Common Lisp stellt zu diesem Zweck Property-Listen und Hash-Tabellen zur Verfügung.

  2. Der Wert ist tatsächlich bereits in einer Liste enthalten. Ein Alist ist im Grunde eine Liste von Paaren, wobei das Auto jedes Paares der Schlüssel ist und das cdr der Wert ist, der mit diesem Schlüssel verbunden ist. Wenn Sie den Schlüssel Wohnzimmer mit ASSOC nachzuschlagen und anzuwenden CDR auf das Ergebnis:

CL-USER> (cdr (assoc 'living-room *edges*)) 
((GARDEN WEST DOOR) (ATTIC UPSTAIRS LADDER)) 

Die Magie dahinter liegt in der Tatsache, dass ein Paar, dessen Auto ist living-room und dessen cdr ist eine Liste der Die beiden Elemente (garden west door) und (attic upstairs ladder) können auch als Drei-Elemente-Liste (living-room (garden west door) (attic upstairs ladder)) betrachtet werden, da die Listen aus Paaren bestehen. Normalerweise

wenn Alists wie zitiert Objekte darstellen, sehen Sie die dargestellten Elemente explizit mit punktierten Paaren, anstatt punning mit Listen Notation, etwa so:

 
(defparameter *edges* 
    '((living-room . ((garden west door) 
        (attic upstairs ladder))) 
    (garden . ((living-room east door))) 
    (attic . ((living-room downstairs ladder))))) 
+0

Ah, schlug mich, um es durch ein paar Minuten! Ja, die Verwendung der gepunktetem Paarsyntax hat mich auch für eine kurze Sekunde in eine Schleife geworfen - gute Beobachtung! – Ken

+0

Wenn ich den Wert bekommen will, warum muss ich cdr? assoc soll Wert bekommen, oder? – Chiron

+2

ASSOC erhält den * Datensatz *. Sie benötigen dann CAR oder CDR, um den Schlüssel/Wert zu erhalten. –

1

Zuerst Assoziationsliste in Lisp ist die gleiche Konzept der Java-Map (Schlüssel-Wert-Bindung)?

Java Map ist eine Schnittstelle. Ein Alist ist eine spezielle Art, eine (verknüpfte) Liste zum Speichern von Schlüssel/Wert-Paaren zu verwenden. Ich glaube nicht, dass Java eingebaute Maps hat, die dieselben Eigenschaften wie ein Alist haben, aber es wäre nicht schwer, eins zu schreiben. Da ein Alist eine Liste ist, bleiben alle Funktionen und Eigenschaften von Listen erhalten.

Für Wohnzimmerschlüssel, wie ist es möglich, mehr als einen Wert zu haben? warum nicht den Wert mit einer Liste einschließen:

Ein Alist ist nicht Teil der Lisp-Syntax. Es ist nur eine Liste, so dass Sie beliebig in die CDR jedes Elements einfügen können. In diesem Fall ist es eine andere CONS-Zelle. ASSOC betrachtet nur das CAR jedes Elements.

(assoc 'living-room *edges*) 
(LIVING-ROOM (GARDEN WEST DOOR) (ATTIC UPSTAIRS LADDER)) 
1

Eine Assoziationsliste ähnelt im Konzept einer Map, insofern beide Schlüssel mit Werten assoziieren.

Es ist nicht notwendig, mehrere Werte in einer anderen Liste zu enthalten, da dies die Bedeutung des Werts ändert.Ich bin mit diesem Buch nicht vertraut, aber es scheint, dass die Art und Weise, dass *EDGES* definiert ist, will der Autor

(cdr (assoc 'Foobar *edges*)) 

eine Liste von Orten, die Sie von Foobar zu bekommen. Wie definiert, ist dies der Fall, wenn einzelne oder mehrere Werte vorhanden sind.

Wenn Sie bei mehreren Werten diese Werte in einer anderen Liste verschachtelt haben, müssen Sie sie nur aus dieser Liste auswählen, wenn Sie sie verwenden möchten. Es würde dir nichts geben und es würde sich von dem Einzelwert-Fall unterscheiden.

5

ASSOC gibt die Cons-Zelle zurück und enthält somit sowohl Schlüssel als auch Wert.

Der Grund ist, dass es so einfach ist, den Wert (oder den Schlüssel) destruktiv zu aktualisieren.

Hier wird das Update hinter SETF versteckt:

CL-USER 11 > (defparameter *edges* 
       (copy-tree 
       '((living-room (garden west door) 
           (attic upstairs ladder)) 
        (garden (living-room east door)) 
        (attic (living-room downstairs ladder))))) 
*EDGES* 

CL-USER 12 > (assoc 'living-room *edges*) 
(LIVING-ROOM (GARDEN WEST DOOR) (ATTIC UPSTAIRS LADDER)) 

CL-USER 13 > (cdr (assoc 'living-room *edges*)) 
((GARDEN WEST DOOR) (ATTIC UPSTAIRS LADDER)) 

CL-USER 14 > (setf (cdr (assoc 'living-room *edges*)) '((garden east door))) 
((GARDEN EAST DOOR)) 

CL-USER 15 > (cdr (assoc 'living-room *edges*)) 
((GARDEN EAST DOOR))