您如何确保关联列表在 Emacs 中维护唯一键 [英] How do you ensure an association list maintains unique keys in Emacs

查看:15
本文介绍了您如何确保关联列表在 Emacs 中维护唯一键的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

鉴于将键添加到像 auto-mode-alist 这样的关联列表的频率,我认为有一些惯用的方法来维护具有唯一键的关联列表,但还没有遇到过.

Given the frequency that keys are added to association lists like auto-mode-alist, I presume there is some idiomatic method for maintaining association lists with unique keys, but have yet to encounter it.

假设我执行以下操作:

(setq alist '())
(add-to-list 'alist '(a . 1))
(add-to-list 'alist '(a . 2))
(add-to-list 'alist '(b . 3))

运行之后,alist 包含 ((b . 3) (a . 2) (a . 1)).我看到 add-to-list 可以采用可选的 compare-fn,所以我认为我可以通过某种方法来获取 ((b . 3) (a . 1)) 作为结果.我也知道我可以为此使用哈希表,但很好奇如何使用关联列表惯用地做到这一点.

After running that, alist contains ((b . 3) (a . 2) (a . 1)). I see that add-to-list can take an optional compare-fn, so I presume there is some method I could pass to get ((b . 3) (a . 1)) as the result. I'm also aware I could use hash tables for this, but was curious how to do it idiomatically with an association list.

推荐答案

并不要求关联列表具有唯一键,如您的示例所示,也没有任何特别的理由期望它们具有唯一键——从根本上说,它只是一个列表列表,对嵌套列表的 car 没有限制.

There's no requirement that association lists have unique keys, as your example shows, nor is there any particular reason to expect them to have unique keys -- at base, it's just a list of lists with no restrictions on the cars of the nested lists.

我相信利用这样一个事实是惯用的,即通过将新对推到列表的前面来覆盖初始键/值对的键没有限制.alists 的一些核心功能在这些方面隐含地工作.例如,这里是 assoc 的文档字符串:

I believe it's idiomatic to exploit the fact that there are no restrictions on the keys to override initial key/value pairs by pushing a new pair onto the front of the list. Some of the core functionality for alists works implicitly along these lines. Here, for example, is the docstring for assoc:

Return non-nil if KEY is `equal' to the car of an element of LIST.
The value is actually the first element of LIST whose car equals KEY.

因此,它只返回第一个元素,而不管列表后面有多少具有相同键的其他元素.这可能是一个非常有用的功能.

Hence, it returns only the first element, regardless of how many other elements come later in the list with the same key. That can be a pretty useful feature.

更新.如果你真的想阻止 add-to-list 隐藏先前的键/值对(尽管你在做因此),您可以定义以下函数并将其传递给 add-to-list 中的 compare-fn 参数(注意它执行零错误检查):

Update. If you really want to prevent add-to-list from shadowing a prior key/value pair (although you're kind of fighting the language in doing so), you can define the following function and pass it to the compare-fn parameter in add-to-list (note that it does zero error-checking):

(defun key-used-p (elt1 elt2)
  "Helper function for add-to-list: returns non-nil if key is
already in use in an association list."
  (eq (car elt1) (car elt2)))

(setq alist '((a . 1) (b . 1) (c . 1)))        ; original list
(add-to-list 'alist '(a . 2) nil #'key-used-p) ; adds nothing because a in use
(add-to-list 'alist '(d . 2) nil #'key-used-p) ; adds (d . 2)

这篇关于您如何确保关联列表在 Emacs 中维护唯一键的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆