unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
* bug#50927: Considering only entries with unique keys in map.el?
@ 2021-10-01  0:55 Okamsn via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2021-10-01  1:56 ` bug#50927: [External] : " Drew Adams
  2021-10-01 12:48 ` Lars Ingebrigtsen
  0 siblings, 2 replies; 4+ messages in thread
From: Okamsn via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2021-10-01  0:55 UTC (permalink / raw)
  To: 50927

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

^ permalink raw reply related	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2021-10-01 12:48 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-10-01  0:55 bug#50927: Considering only entries with unique keys in map.el? Okamsn via Bug reports for GNU Emacs, the Swiss army knife of text editors
2021-10-01  1:56 ` bug#50927: [External] : " Drew Adams
2021-10-01  2:17   ` Michael Heerdegen
2021-10-01 12:48 ` Lars Ingebrigtsen

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