Lisp中关联列表的基本问题

Lisp中关联列表的基本问题,lisp,common-lisp,land-of-lisp,Lisp,Common Lisp,Land Of Lisp,我在读《Lisp之地》(顺便说一句,这是我读过的最好的技术书籍之一),我偶然发现了一个关联列表 首先,Lisp中的关联列表与Java的Map(键值绑定)的概念相同吗? 对于客厅钥匙,如何可能有多个值?为什么不用列表括起该值: (living-room ((garden west door) (attic upstairs ladder))) 是的,关联列表是表示键值关联的一种方式。Lisp为此提供的其他结构是属性列表和哈希表 该值实际上已包含在列表中。alist基本上是一个对的列表,其

我在读《Lisp之地》(顺便说一句,这是我读过的最好的技术书籍之一),我偶然发现了一个关联列表

首先,Lisp中的关联列表与Java的Map(键值绑定)的概念相同吗?
对于客厅钥匙,如何可能有多个值?为什么不用列表括起该值:

    (living-room ((garden west door) (attic upstairs ladder)))
  • 是的,关联列表是表示键值关联的一种方式。Lisp为此提供的其他结构是属性列表和哈希表

  • 该值实际上已包含在列表中。alist基本上是一个对的列表,其中每对的car是密钥,cdr是与该密钥相关联的值。如果您与ASSOC一起查找关键客厅并对结果应用CDR:

  • 首先,Lisp中的关联列表是否与Java的Map(键值绑定)的概念相同

    Java的映射是一个接口。列表是使用(链接)列表存储键值对的一种特定方式。我认为Java没有任何内置映射具有与列表相同的属性,但编写一个映射并不困难。因为列表是一个列表,所以列表的所有函数和属性仍然有效

    对于客厅钥匙,如何可能有多个值?为什么不用列表括起该值:

    列表不是Lisp语法的一部分。它只是一个列表,所以您可以在每个元素的CDR中放入您想要的任何内容。在这种情况下,它是另一个CONS单元
    ASSOC
    只查看每个元素的汽车

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

    关联列表在概念上类似于映射,因为两者都将键与值相关联

    不需要在另一个列表中包含多个值,因为这会更改值的含义。我对这本书不熟悉,但似乎作者想要的是定义
    *EDGES*
    的方式

    (cdr (assoc 'Foobar *edges*))
    
    成为你可以从Foobar获得的地方列表。根据定义,如果存在单个或多个值,则为真


    如果,当有多个值时,您将这些值嵌套在另一个列表中,那么当您想要使用它们时,您只需从该列表中选择它们。它不会给你任何东西,它会使它不同于单值的情况。

    ASSOC返回cons单元格,因此包含key和value

    原因是这样可以轻松地以破坏性方式更新值(或键)

    此处更新隐藏在SETF后面:

    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))
    

    啊,比我快几分钟!是的,不使用点对语法也让我陷入了一个循环——很好的观察!如果我想得到这个值,为什么我必须cdr?assoc应该得到值,对吗?assoc得到记录。然后您需要CAR或CDR来获取密钥/值。
    (assoc 'living-room *edges*)
    (LIVING-ROOM (GARDEN WEST DOOR) (ATTIC UPSTAIRS LADDER))
    
    (cdr (assoc 'Foobar *edges*))
    
    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))