Path: csiph.com!feeder.erje.net!1.eu.feeder.erje.net!news.mb-net.net!open-news-network.org!.POSTED.207.227.197.178.dynamic.wless.zhbmb00p-cgnat.res.cust.swisscom.ch!not-for-mail From: Thomas 'PointedEars' Lahn Newsgroups: comp.lang.javascript Subject: Re: using Map Date: Thu, 14 Jun 2018 17:13:50 +0200 Organization: PointedEars Software (PES) Lines: 177 Message-ID: <5317938.iMaMEg0OTm@PointedEars.de> References: <18902741.ZdnXStS6ea@PointedEars.de> <1854071.sLym9PP3UP@PointedEars.de> Reply-To: Thomas 'PointedEars' Lahn Mime-Version: 1.0 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: 8Bit Injection-Info: gwaiyur.mb-net.net; posting-host="207.227.197.178.dynamic.wless.zhbmb00p-cgnat.res.cust.swisscom.ch:178.197.227.207"; logging-data="25646"; mail-complaints-to="abuse@open-news-network.org" User-Agent: KNode/4.14.2 Face: iVBORw0KGgoAAAANSUhEUgAAADAAAAAwBAMAAAClLOS0AAAAGFBMVEXTxa4RFk5dUWANED8PFEfy7+MGBiW+n3ZNF/QuAAACaElEQVQ4jVXUwVOcMBQG8Dc7Rc4PUntdWV2uxjDpGaGeozOp1woar4jd5t/v9wLstMwsA/ntlxdCAgUc1hjTc9/JCZfGoo3wG3HdmdAWrIJRHe7GM/TmpY5VFefuVcAkkPbLIaN8rmPmjloyZxgyR3GuJ4K0AGtJ2htz8o7yqikm759fldQXaMpbDzjKAG+8v+AugVTOPO5DOjLvGtUYQwh0CPjnVMyGd+8/GfUB5nLKJDD2aLDh5HYyMDJGDwQIo2ZmZcKbowNmAdB/AzyFhrmF2MHRb0QJJfaAnwGB6orZhoykLzJtGwF/xpYxI1dswomiUj3gTuAIqCn/4C7cULwGNBtwMTk3Y4LfKB5YUaOKBKYtpplm7u0vip8tU1NWWyI/7XdcSuIDoMt6rVHMWT0DbjHPGqDqZVSa6zleLcUTcIKLoMv3ueJluALtAo9B302zPPlrtiVScRdCjXvVh3e3JpYa/jjkuC9N+LrBMlz/eAN4eQijX2EdLo6c5tGGHwLyHFtXk89dDGHwCVhG9T0S/j55AhRZgkMCmUQXJ49TnS1wnQDvw0eAh9ICeMmEFbCnPMFzjAvsWoEWEFdYEx+S0MoUZ1gT1wId8+AF3Bl2OoEu906AUHx5VLw/gXYg/x84loOah/2UYNrgiwSwGO7RfUzVBbx/kgpckumGOi6QirtD6gkLTitbnxNol47S2jVc2vsN5kPqaAHT8uUdAJM4v/DanjYOwmUjWznGfwB7sGtAtor5BgofDuzaRj4kSQAqDakTsKORa3Q3xKi3gE1fhl71KRMqrdZ2AWNNg/YOhQyrVBnb+i+nEg4bsDA+egAAAABJRU5ErkJggg== X-User-ID: U2FsdGVkX18zMWqCaVYgrpLQQO4ahosVOiGIMZYX6stabFRHcKsp5A== Cancel-Lock: sha1:o97JVCZC7Y/xkfsSBKDba+ZMBvU= X-Face: %i>XG-yXR'\"2P/C_aO%~;2o~?g0pPKmbOw^=NT`tprDEf++D.m7"}HW6.#=U:?2GGctkL,f89@H46O$ASoW&?s}.k+&. After experimenting with creating and then getting and setting property > values of an object that is a Map's value I went on to work with > multiple Maps each of which is meant to start with the same values. OK, but your follow-up had nothing to do with what what you posted before and what I suggested to do instead. We cannot have a useful discussion if you post every stray thought that just entered your mind, without regard to what was said before. >>> when I changed the value in one map the corresponding value in all maps >>> changed as well. >> >> No. Why do you not read the Specification? Why do you not try it out? > > I populated a map using an array of objects. > I created multiple copies of the map. How? > When I changed the property value in one of a map's value all the > corresponding values in the other maps changed as well. Then you did something wrong. Here is how you efficiently construct, populate, and clone a Map instance: | > var map = new Map([["foo", "bar"]]); | <- undefined | | > map | <- :> Map(1) {"foo" => "bar"} | | > var map2 = new Map(map); | <- undefined | | > map2 | <- Map(1) {"foo" => "bar"} | | > map2.set("foo", "baz"); | <- Map(1) {"foo" => "baz"} | | > map2 | <- Map(1) {"foo" => "baz"} | | > map | <- Map(1) {"foo" => "bar"} > I have looked at the spec but I didn't see anywhere that dealt with > making copies of a Map. ,- | | 23.1.1.1 Map ( [ /iterable/ ] ) | | When the Map function is called with optional argument, the following | steps are taken: | | 1. If NewTarget is *undefined*, throw a *TypeError* exception. | 2. Let /map/ be ? OrdinaryCreateFromConstructor(NewTarget, | "%MapPrototype%", « [[MapData]] »). This creates a new empty Map instance referred to by /map/. | 3. Set /map/.[[MapData]] to a new empty List. | 4. If /iterable/ is not present, let /iterable/ be *undefined*. | 5. If /iterable/ is either *undefined* or *null*, let /iter/ be undefined. | 6. Else, | a. Let /adder/ be ? Get(/map/, "set"). (For brevity, in the following I am using the wording “Array” instead of the precise wording “reference to an Array instance”.) This is where Map.prototype.set() is defined as the method to use to add items to the new Map, so that passing an Array (/iterable/) of Arrays to the constructor is functionally equivalent to consecutive calls of Map.prototype.set() immediately after construction. (BTW, as .set() returns the Map, you can also chain .set() calls – another way to DRY, and a way to have a populated Map without a name to store the reference to it). | b. If IsCallable(/adder/) is *false*, throw a *TypeError* exception. | c. Let /iter/ be ? GetIterator(/iterable/). This is where the iterator for a passed Array is retrieved. It follows that if /iterable/ is a Map instead, *its* iterator is retrieved, which returns key-value pairs as a 2-element Array – so for cloning a Map, you can simply pass a Map to the Map constructor (also see “NOTE” below). [This is a useful feature that one should provide for one’s custom object types. Calling a “clone” or conversion method should be the exception.] Currently, the MDN article mentions this only implicitly. It is saying: | iterable | An Array or other iterable object whose elements are key-value pairs | […] | | Description | | A Map object iterates its elements in insertion order — a for...of | loop returns an array of [key, value] for each iteration. […] [I did not know for sure as I had not read the Specification for this, so *I* *just* *tried* *it* *out*.] | 7. If /iter/ is *undefined*, return map. If the passed object is not iterable, the constructed Map is empty. | 8. Repeat, This is where iteration will commence. | a. Let /next/ be ? IteratorStep(iter). | b. If /next/ is *false*, return /map/. This is the case if all elements of the Array or items of the Map have been processed, so iteration will stop, and the new Map will be returned. | c. Let /nextItem/ be ? IteratorValue(next). | d. If Type(/nextItem/) is not Object, then | i. Let /error/ be Completion{[[Type]]: throw, | [[Value]]: a newly created *TypeError* object, | [[Target]]: empty}. | ii. Return ? IteratorClose(/iter/, /error/). | e. Let /k/ be Get(/nextItem/, "0"). | f. If /k/ is an abrupt completion, return ? IteratorClose(/iter/, /k/). | g. Let /v/ be Get(nextItem, "1"). | h. If /v/ is an abrupt completion, return ? IteratorClose(/iter/, /v/). | i. Let status be Call(/adder/, map, « k.[[Value]], v.[[Value]] »). ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ This is where each element/item will be added as a key-value pair. | j. If status is an abrupt completion, return ? IteratorClose(iter, | status). | | NOTE | | If the parameter iterable is present, it is expected to be an object that | implements an @@iterator method that returns an iterator object that ^^^^^^^^^^^^^^^^^^^^^^^ | produces a two element array-like object whose first element is a value ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | that will be used as a Map key and whose second element is the value to ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | associate with that key. ^^^^^^^^^^^^^^^^^^^^^^^^ Which I said above. > (BTW I find the spec intimidating.) You must learn to control your emotions so that they do not control you. In fact, although the ECMAScript Language Specification necessarily has become more complex as language features were added in each Edition, its usability has steadily improved. Now there is ∙ a scroll-sensitive table of contents (TOC) as ∙ a tree-view in ∙ a responsive sidebar, ∙ an input control for full-text search in the TOC above that, and in the text, ∙ all referenced algorithms can be navigated to, and ∙ all variable references can be highlighted, by hyperlinks. -- PointedEars FAQ: | | Twitter: @PointedEars2 | Please do not cc me./Bitte keine Kopien per E-Mail.