Designing a MultiMap (in DOM, would like to be consistent with ES)

Mark S. Miller erights at
Fri Nov 30 15:53:09 PST 2012

On Fri, Nov 30, 2012 at 3:38 PM, Tab Atkins Jr. <jackalmage at> wrote:
> As I expressed in an earlier thread to es-discuss, Anne van Kesteren
> is currently writing the URL spec, and as part of that he's designing
> the URLQuery interface, which is essentially a MultiMap (a Map where
> one key can map to multiple values).  I was convinced in the previous
> thread that trying to make a MultiMap a subclass of Map was a red
> herring, and that MultiMap should instead be a parallel class to Map,
> like Set is.
> So, I've been working with Anne to design the URLQuery interface
> against a speculative future MultiMap API.  I figured it would be a
> good idea to run it against es-discuss before we settle on it.  ^_^
> Note that right now, we've trimmed down the MultiMap features of
> URLQuery to the bare minimum necessary (getAll and append), to avoid
> forcing tc39's hand as much as possible.
> Our approach is that MultiMap should be able to masquerade as a Map,

This means that you're still trying to make MultiMap a subtype of Map,
whether it is a subclass or not. That herring still seems pink. But
I'll go with this premise below.

> adding the additional functionality in overloads or variant functions.
>  Conceptually, imagine the MultiMap as an ordered list of (k,v) pairs,
> with no restriction (compare to Map, which places a restriction that
> there are no pairs with the same k).
> get(k) => returns the value of the first (k,_) pair, or else undefined.
> getAll(k) => returns a (possibly empty) array of all values associated
> with the key
> set(k,v) => finds the first (k,_) pair, and replaces its value with v.
> Removes any other (k,_) pairs. If there were no (k,_) pairs, adds
> (k,v) to the end of the map.
> setAll(k, [v]) => replaces (k,_) pairs until either the input list or
> the existing pairs runs out. Removes any other (k,_) pairs. If there
> were leftover values, adds (k,v) pairs to the end of the map.
> append(k,v) => adds (k,v) to the end of the map.
> appendAll(k,[v]) => adds multiple values.  Needed?
> has(k, v?) => return true/false if a (k,_) pair is in the map. If the
> second arg is provided, returns true/false if (k,v) is in the map.
> delete(k, v?) => removes all (k,_) pairs from the map.  If the second
> arg is provided, removes only the (k,v) pairs.
> For iterators, obviously keys() would only return unique keys.

That seems to conflict with the spirit of the rest of your design.
Continue to think of the MultiMap as an ordered list of k,v pairs.
keys() should return all the successive k elements in order, including
duplicates. values() does likewise for the v elements, and items()
does likewise for the pairs. Everything is parallel, has the same
cardinality and order, and zips up just fine.

>  Unsure
> whether values() should return individual values, or arrays of values
> associate with each key (and same for items()).  I lean toward the
> latter, so that the iterators returned by keys() and values() are
> comparable (zipping them gets you the same value as calling items()).
> Would we want a second items()-like iterator that returns the
> individual (k,v) pairs?
> Thoughts?
> ~TJ
> _______________________________________________
> es-discuss mailing list
> es-discuss at


More information about the es-discuss mailing list