LISP全局alist变量

3

我是LISP的新手,下面是我对全局变量的问题。

我的目标是创建一个“alist”来存储键值对。以下是我的示例代码:

(setq *x* '())

(acons 'apple 'fruit *x*)

*x*

(first *x*)

我希望在添加了(apple.fruit)之后,我的输出看起来像是x应该是((apple.fruit)),但是这是我得到的结果(在上述代码加载时):

CL-USER> 
NIL
((APPLE . FRUIT))
NIL  <--- this is still nil?
NIL

有人能帮我解决这个问题吗,因为我不确定为什么不能给变量x赋值。

另外,我还有一个关于alist的问题:
是否有一种方法可以通过键在列表中查找元素?
例如,对于上面的列表,如何使用键apple来查找其相应的值fruit

谢谢


1
欢迎来到StackOverflow!当人们发布有用的答案时,您应该通过点击该答案的复选标记选择最有用的答案作为“已接受”的答案。 - mbeckish
2个回答

4

函数acons没有副作用,即它不会修改*x*

你需要使用setq将结果设置为acons的结果,才能使其保留在*x*中:

(setq *x* (acons 'apple 'fruit *x*))

对于检索,可以使用assoc(cdr (assoc 'apple *x*)) ==> FRUIT - Will Ness

1

如果您想进行函数式编程,那么可变全局变量绝对不是一种选择。

函数式编程大多关注通过使用参数调用函数进行计算。

通常解决方案是递归的。

假设我们有一个水果和价格列表,我们想要为每个水果类别获得价格总和。让我们尝试使用ACONS的递归解决方案。

(defun note-category-price (type price sums)
  (let ((pair (assoc type sums)))
    (if pair
        (progn (incf (cdr pair) price) sums)
      (acons type price sums))))

在上述函数中,您可以看到该函数直接返回调用ACONS的结果。它没有被存储。
(defun compute-price-sums (data sums)
  (if (null data)
      sums
    (compute-price-sums (rest (rest data))
                        (note-category-price (first data)
                                             (second data)
                                             sums))))

在上述函数中,扩展数据结构将在递归调用中使用。
例如:
CL-USER 22 > (compute-price-sums
              '(apple 10 orange 20 banana 10 apple 20
                grape 5 orange 75 apple 30 peach 30
                orange 90 apple 20)
              nil)

((PEACH . 30) (GRAPE . 5) (BANANA . 10) (ORANGE . 185) (APPLE . 80))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接