From: Okamsn via "Bug reports for GNU Emacs, the Swiss army knife of text editors" <bug-gnu-emacs@gnu.org>
To: 50927@debbugs.gnu.org
Subject: bug#50927: Considering only entries with unique keys in map.el?
Date: Fri, 01 Oct 2021 00:55:21 +0000 [thread overview]
Message-ID: <9fda32d4-5c09-a047-18aa-a792211ffa06@protonmail.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 845 bytes --]
Some kinds of maps, such as alists and plists, can contain duplicate
keys. These duplicates are effectively ignored in functions like
`map-elt`, but are not ignored in functions like `map-do` or `map-length`.
To me, it would make more sense if these functions only considered the
valid entries in the map. For example,
(map-pairs '(a 1 b 2 a 3))
currently returns '((a . 1) (b . 2) (a . 3)), even though '(a . 3) is
meant to be ignored in actual usage, as it is preceded by an earlier
entry with the same key. This is a misleading behavior.
I do not know whether the current behavior is desirable. Is it?
Please consider changing the library so that the duplicate,
meant-to-be-ignored entries are actually ignored for functions that
operate on the entire map.
I have attached an example diff.
Thank you.
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: map-uniq.diff --]
[-- Type: text/x-patch; name=map-uniq.diff, Size: 1838 bytes --]
diff --git a/lisp/emacs-lisp/map.el b/lisp/emacs-lisp/map.el
index 77431f0c59..9db2ddd95f 100644
--- a/lisp/emacs-lisp/map.el
+++ b/lisp/emacs-lisp/map.el
@@ -202,6 +202,25 @@ map-nested-elt
map)
default))
+(defun map--remove-duplicate-keys (map)
+ "Make a version of MAP without duplicated keys.
+
+Unlike hash tables, association and property lists allow
+duplicate keys in the data structure. This function returns the
+map with such keys and their respective data removed."
+ (if (map--plist-p map)
+ (let ((found-keys)
+ (result))
+ (while map
+ (let ((key (pop map))
+ (value (pop map)))
+ (unless (member key found-keys)
+ (push key found-keys)
+ (push key result)
+ (push value result))))
+ (nreverse result))
+ (seq-uniq map (lambda (a b) (equal (car a) (car b))))))
+
(cl-defgeneric map-keys (map)
"Return the list of keys in MAP.
The default implementation delegates to `map-apply'."
@@ -234,6 +253,7 @@ map-length
(hash-table-count map))
(cl-defmethod map-length ((map list))
+ (setq map (map--remove-duplicate-keys map))
(if (map--plist-p map)
(/ (length map) 2)
(length map)))
@@ -489,7 +509,7 @@ map-apply
(cl-call-next-method)
(mapcar (lambda (pair)
(funcall function (car pair) (cdr pair)))
- map)))
+ (map--remove-duplicate-keys map))))
(cl-defmethod map-apply (function (map hash-table))
(let (result)
@@ -504,6 +524,7 @@ map-apply
map))
(cl-defmethod map-do (function (map list))
+ (setq map (map--remove-duplicate-keys map))
(if (map--plist-p map)
(while map
(funcall function (pop map) (pop map)))
next reply other threads:[~2021-10-01 0:55 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-10-01 0:55 Okamsn via Bug reports for GNU Emacs, the Swiss army knife of text editors [this message]
2021-10-01 1:56 ` bug#50927: [External] : bug#50927: Considering only entries with unique keys in map.el? Drew Adams
2021-10-01 2:17 ` Michael Heerdegen
2021-10-01 12:48 ` Lars Ingebrigtsen
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/emacs/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=9fda32d4-5c09-a047-18aa-a792211ffa06@protonmail.com \
--to=bug-gnu-emacs@gnu.org \
--cc=50927@debbugs.gnu.org \
--cc=okamsn@protonmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).