Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.javascript > #35214 > unrolled thread

get set value in array of objects

Started byAndrew Poulos <ap_prog@hotmail.com>
First post2018-06-12 10:50 +1000
Last post2018-06-14 07:11 -0700
Articles 19 — 8 participants

Back to article view | Back to comp.lang.javascript


Contents

  get set value in array of objects Andrew Poulos <ap_prog@hotmail.com> - 2018-06-12 10:50 +1000
    Re: get set value in array of objects "Evertjan." <exxjxw.hannivoort@inter.nl.net> - 2018-06-12 16:40 +0200
    Re: get set value in array of objects "Christoph M. Becker" <cmbecker69@arcor.de> - 2018-06-12 17:12 +0200
    Re: get set value in array of objects Cezary Tomczyk <cezary.tomczyk@gmail.com> - 2018-06-12 17:36 +0200
      using Map Was: Re: get set value in array of objects Andrew Poulos <ap_prog@hotmail.com> - 2018-06-13 13:56 +1000
        Re: using Map Was: Re: get set value in array of objects Andrew Poulos <ap_prog@hotmail.com> - 2018-06-13 14:43 +1000
          Re: using Map Was: Re: get set value in array of objects Andrew Poulos <ap_prog@hotmail.com> - 2018-06-13 17:17 +1000
            Re: using Map Was: Re: get set value in array of objects Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2018-06-13 23:32 +0200
        Re: using Map Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2018-06-13 18:47 +0200
          Re: using Map Andrew Poulos <ap_prog@hotmail.com> - 2018-06-14 21:52 +1000
            Re: using Map Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2018-06-14 14:31 +0200
              Re: using Map Andrew Poulos <ap_prog@hotmail.com> - 2018-06-14 23:52 +1000
                Re: using Map Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2018-06-14 17:13 +0200
                  Re: using Map "Mark-" <nospam@mapson.xyz> - 2018-06-14 16:25 +0000
            Re: using Map "Evertjan." <exxjxw.hannivoort@inter.nl.net> - 2018-06-14 16:11 +0200
    Re: get set value in array of objects Ben Bacarisse <ben.usenet@bsb.me.uk> - 2018-06-12 16:40 +0100
      Re: get set value in array of objects Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2018-06-13 05:18 +0200
        Re: get set value in array of objects Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2018-06-13 05:25 +0200
    Re: get set value in array of objects Julio Di Egidio <julio@diegidio.name> - 2018-06-14 07:11 -0700

#35214 — get set value in array of objects

FromAndrew Poulos <ap_prog@hotmail.com>
Date2018-06-12 10:50 +1000
Subjectget set value in array of objects
Message-ID<m7idnSrECaxLhYLGnZ2dnUU7-fvNnZ2d@westnet.com.au>
Say I have an array like this

var objArray = [
     { id:0, name:'Jonah',   otherProp:321 },
     { id:1, name:'Andrew',  otherProp:648 },
     { id:2, name:'Another', otherProp:850 },
     { id:3, name:'Quite',   otherProp:146 },
     { id:4, name:'Mary',    otherProp:984 }
];

except that the objects have many more properties and the array has many 
more elements.


To get, say the 'name' value for the object with an id = 3 I'm using:

var val = objArray.find(function(obj) {
   return (obj.id === 3 ? obj.name : false);
});


And to set the 'name' value for the object with an id = 3 I'm using:

var ind = objArray.findIndex(function(obj) {
   return obj.id === 3;
});

objArray[ind]['name'] = "Fred";


It works but I'm wondering if someone could show a "better" way.

Andrew Poulos

[toc] | [next] | [standalone]


#35215

From"Evertjan." <exxjxw.hannivoort@inter.nl.net>
Date2018-06-12 16:40 +0200
Message-ID<XnsA8FFA996589E6eejj99@194.109.6.166>
In reply to#35214
Andrew Poulos <ap_prog@hotmail.com> wrote on 12 Jun 2018 in 
comp.lang.javascript:

> Say I have an array like this
> 
> var objArray = [
>      { id:0, name:'Jonah',   otherProp:321 },
>      { id:1, name:'Andrew',  otherProp:648 },
>      { id:2, name:'Another', otherProp:850 },
>      { id:3, name:'Quite',   otherProp:146 },
>      { id:4, name:'Mary',    otherProp:984 }
> ];
> 
> except that the objects have many more properties and the array has many 
> more elements.
> 
> 
> To get, say the 'name' value for the object with an id = 3 I'm using:
> 
> var val = objArray.find(function(obj) {
>    return (obj.id === 3 ? obj.name : false);
>});
> 
> 
> And to set the 'name' value for the object with an id = 3 I'm using:
> 
> var ind = objArray.findIndex(function(obj) {
>    return obj.id === 3;
>});
> 
> objArray[ind]['name'] = "Fred";
> 
> 
> It works but I'm wondering if someone could show a "better" way.

'use strict';

let objArray = [
     { id:0, name:'Jonah',   otherProp:321 },
     { id:1, name:'Andrew',  otherProp:648 },
     { id:2, name:'Another', otherProp:850 },
     { id:3, name:'Quite',   otherProp:146 },
     { id:3, name:'Not quite', otherProp:9 },
     { id:4, name:'Mary',    otherProp:984 }
];

let findName = (idNr) => {
   let test = (obj) => obj.id === idNr;
   let ob = objArray.find(test);
   return (ob !== undefined) ? ob.name : 'Not found';
};

document.write(findName(3) + '<br>');
document.write(findName(5) + '<br>');



-- 
Evertjan.
The Netherlands.
(Please change the x'es to dots in my emailaddress)

[toc] | [prev] | [next] | [standalone]


#35216

From"Christoph M. Becker" <cmbecker69@arcor.de>
Date2018-06-12 17:12 +0200
Message-ID<pfonrv$fvu$1@solani.org>
In reply to#35214
On 12.06.2018 at 02:50, Andrew Poulos wrote:

> Say I have an array like this
> 
> var objArray = [
>     { id:0, name:'Jonah',   otherProp:321 },
>     { id:1, name:'Andrew',  otherProp:648 },
>     { id:2, name:'Another', otherProp:850 },
>     { id:3, name:'Quite',   otherProp:146 },
>     { id:4, name:'Mary',    otherProp:984 }
> ];
> 
> except that the objects have many more properties and the array has many
> more elements.
> 
> 
> To get, say the 'name' value for the object with an id = 3 I'm using:
> 
> var val = objArray.find(function(obj) {
>   return (obj.id === 3 ? obj.name : false);
> });
> 
> 
> And to set the 'name' value for the object with an id = 3 I'm using:
> 
> var ind = objArray.findIndex(function(obj) {
>   return obj.id === 3;
> });
> 
> objArray[ind]['name'] = "Fred";
> 
> 
> It works but I'm wondering if someone could show a "better" way.

If you're doing the lookup mostly by ID, consider to use some kind of
map instead.  For the given example you could even do:

  objArray[3].name

to get the name, and

  objArray[3].name = "Fred"

to set it.

-- 
Christoph M. Becker

[toc] | [prev] | [next] | [standalone]


#35217

FromCezary Tomczyk <cezary.tomczyk@gmail.com>
Date2018-06-12 17:36 +0200
Message-ID<pfopa6$13s0$1@csiph.com>
In reply to#35214
On 12/06/2018 02:50, Andrew Poulos wrote:
> Say I have an array like this
> 
> var objArray = [
>      { id:0, name:'Jonah',   otherProp:321 },
>      { id:1, name:'Andrew',  otherProp:648 },
>      { id:2, name:'Another', otherProp:850 },
>      { id:3, name:'Quite',   otherProp:146 },
>      { id:4, name:'Mary',    otherProp:984 }
> ];
> 
> except that the objects have many more properties and the array has many 
> more elements.
> 
> 
> To get, say the 'name' value for the object with an id = 3 I'm using:
> 
> var val = objArray.find(function(obj) {
>    return (obj.id === 3 ? obj.name : false);
> });
> 
> 
> And to set the 'name' value for the object with an id = 3 I'm using:
> 
> var ind = objArray.findIndex(function(obj) {
>    return obj.id === 3;
> });
> 
> objArray[ind]['name'] = "Fred";
> 
> 
> It works but I'm wondering if someone could show a "better" way.
> 
> Andrew Poulos

Consider using Map: 
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map

-- 
Cezary Tomczyk
http://www.ctomczyk.pl/
https://www.aslint.org/

[toc] | [prev] | [next] | [standalone]


#35222 — using Map Was: Re: get set value in array of objects

FromAndrew Poulos <ap_prog@hotmail.com>
Date2018-06-13 13:56 +1000
Subjectusing Map Was: Re: get set value in array of objects
Message-ID<AuqdnSaYXed-CL3GnZ2dnUU7-LnNnZ2d@westnet.com.au>
In reply to#35217
On 13/06/2018 1:36 AM, Cezary Tomczyk wrote:

> Consider using Map: 
> https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map 


I'm testing using a Map and I'm a bit confused getting/setting property 
values within a value's object.

let objArray = new Map();

objArray.set(0, { id:0, name:'Jonah',   otherProp:321 });
objArray.set(1, { id:1, name:'Andrew',  otherProp:648 });
objArray.set(2, { id:2, name:'Another', otherProp:850 });
objArray.set(3, { id:3, name:'Quite',   otherProp:146 });
objArray.set(4, { id:4, name:'Mary',    otherProp:984 });

To get

let n = objArray.get(3).name;
// returns 'Quite'

but to, say, change the name to 'Contrary' I should do...

n = objArray.get(3);
n.name = 'Contrary';
objArray.set(3, n);

Is that correct?


Andrew Poulos

[toc] | [prev] | [next] | [standalone]


#35223 — Re: using Map Was: Re: get set value in array of objects

FromAndrew Poulos <ap_prog@hotmail.com>
Date2018-06-13 14:43 +1000
SubjectRe: using Map Was: Re: get set value in array of objects
Message-ID<pLGdnbJBttifPL3GnZ2dnUU7-cnNnZ2d@westnet.com.au>
In reply to#35222
On 13/06/2018 1:56 PM, Andrew Poulos wrote:
> On 13/06/2018 1:36 AM, Cezary Tomczyk wrote:
> 
>> Consider using Map: 
>> https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map 
> 
> 
> 
> I'm testing using a Map and I'm a bit confused getting/setting property 
> values within a value's object.
> 
> let objArray = new Map();
> 
> objArray.set(0, { id:0, name:'Jonah',   otherProp:321 });
> objArray.set(1, { id:1, name:'Andrew',  otherProp:648 });
> objArray.set(2, { id:2, name:'Another', otherProp:850 });
> objArray.set(3, { id:3, name:'Quite',   otherProp:146 });
> objArray.set(4, { id:4, name:'Mary',    otherProp:984 });
> 
> To get
> 
> let n = objArray.get(3).name;
> // returns 'Quite'
> 
> but to, say, change the name to 'Contrary' I should do...
> 
> n = objArray.get(3);
> n.name = 'Contrary';
> objArray.set(3, n);

To answer my own question, to set, it seems that I can simply do

objArray.get(3).name = 'Contrary';


Andrew Poulos

[toc] | [prev] | [next] | [standalone]


#35224 — Re: using Map Was: Re: get set value in array of objects

FromAndrew Poulos <ap_prog@hotmail.com>
Date2018-06-13 17:17 +1000
SubjectRe: using Map Was: Re: get set value in array of objects
Message-ID<jNidnfkVIMxiWb3GnZ2dnUU7-YednZ2d@westnet.com.au>
In reply to#35223
On 13/06/2018 2:43 PM, Andrew Poulos wrote:
> On 13/06/2018 1:56 PM, Andrew Poulos wrote:
>> On 13/06/2018 1:36 AM, Cezary Tomczyk wrote:
>>
>>> Consider using Map: 
>>> https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map 
>>
>>
>>
>>
>> I'm testing using a Map and I'm a bit confused getting/setting 
>> property values within a value's object.
>>
>> let objArray = new Map();
>>
>> objArray.set(0, { id:0, name:'Jonah',   otherProp:321 });
>> objArray.set(1, { id:1, name:'Andrew',  otherProp:648 });
>> objArray.set(2, { id:2, name:'Another', otherProp:850 });
>> objArray.set(3, { id:3, name:'Quite',   otherProp:146 });
>> objArray.set(4, { id:4, name:'Mary',    otherProp:984 });
>>
>> To get
>>
>> let n = objArray.get(3).name;
>> // returns 'Quite'
>>
>> but to, say, change the name to 'Contrary' I should do...
>>
>> n = objArray.get(3);
>> n.name = 'Contrary';
>> objArray.set(3, n);
> 
> To answer my own question, to set, it seems that I can simply do
> 
> objArray.get(3).name = 'Contrary';

The only problem being that if the 'name' property doesn't exist it 
throws an error - so some tolerance is needed.

Andrew Poulos

[toc] | [prev] | [next] | [standalone]


#35226 — Re: using Map Was: Re: get set value in array of objects

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2018-06-13 23:32 +0200
SubjectRe: using Map Was: Re: get set value in array of objects
Message-ID<2513390.l9jetEAcx8@PointedEars.de>
In reply to#35224
Andrew Poulos wrote:

> On 13/06/2018 2:43 PM, Andrew Poulos wrote:
>> objArray.get(3).name = 'Contrary';
> 
> The only problem being that if the 'name' property doesn't exist it
> throws an error […]

A “TypeError” exception will be thrown then only if the item is sealed (not 
extensible, see Object.seal()) and it is strict mode code.  Otherwise either 
nothing happens (sealed, non-strict), or the property will be created on the 
item (not sealed).

Another possibility is that the item is a Proxy instance with a setter that 
prevents the addition of properties to its target, in which case the 
behavior is either implementation-defined or user-defined.

-- 
PointedEars
FAQ: <http://PointedEars.de/faq> | <http://PointedEars.de/es-matrix>
<https://github.com/PointedEars> | <http://PointedEars.de/wsvn/>
Twitter: @PointedEars2 | Please do not cc me./Bitte keine Kopien per E-Mail.

[toc] | [prev] | [next] | [standalone]


#35225 — Re: using Map

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2018-06-13 18:47 +0200
SubjectRe: using Map
Message-ID<18902741.ZdnXStS6ea@PointedEars.de>
In reply to#35222
Andrew Poulos wrote:

> let objArray = new Map();
> 
> objArray.set(0, { id:0, name:'Jonah',   otherProp:321 });
> objArray.set(1, { id:1, name:'Andrew',  otherProp:648 });
> objArray.set(2, { id:2, name:'Another', otherProp:850 });
> objArray.set(3, { id:3, name:'Quite',   otherProp:146 });
> objArray.set(4, { id:4, name:'Mary',    otherProp:984 });

DRY:

  let objArray = [
    {id: 0, name: 'Jonah',   otherProp:321},
    {id: 1, name: 'Andrew',  otherProp:648},
    {id: 2, name: 'Another', otherProp:850},
    {id: 3, name: 'Quite',   otherProp:146},
    {id: 4, name: 'Mary',    otherProp:984}
  ];

  let map = new Map(objArray.map((el) => [el.id, el]));

<https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map>

-- 
PointedEars
FAQ: <http://PointedEars.de/faq> | <http://PointedEars.de/es-matrix>
<https://github.com/PointedEars> | <http://PointedEars.de/wsvn/>
Twitter: @PointedEars2 | Please do not cc me./Bitte keine Kopien per E-Mail.

[toc] | [prev] | [next] | [standalone]


#35228 — Re: using Map

FromAndrew Poulos <ap_prog@hotmail.com>
Date2018-06-14 21:52 +1000
SubjectRe: using Map
Message-ID<s5adnVTPJv1_y7_GnZ2dnUU7-SnNnZ2d@westnet.com.au>
In reply to#35225
On 14/06/2018 2:47 AM, Thomas 'PointedEars' Lahn wrote:
> Andrew Poulos wrote:
> 
>> let objArray = new Map();
>>
>> objArray.set(0, { id:0, name:'Jonah',   otherProp:321 });
>> objArray.set(1, { id:1, name:'Andrew',  otherProp:648 });
>> objArray.set(2, { id:2, name:'Another', otherProp:850 });
>> objArray.set(3, { id:3, name:'Quite',   otherProp:146 });
>> objArray.set(4, { id:4, name:'Mary',    otherProp:984 });
> 
> DRY:
> 
>    let objArray = [
>      {id: 0, name: 'Jonah',   otherProp:321},
>      {id: 1, name: 'Andrew',  otherProp:648},
>      {id: 2, name: 'Another', otherProp:850},
>      {id: 3, name: 'Quite',   otherProp:146},
>      {id: 4, name: 'Mary',    otherProp:984}
>    ];
> 
>    let map = new Map(objArray.map((el) => [el.id, el]));

When I then did

let map2 = new Map(map);
let map3 = new Map(map);
let map4 = new Map(map);

then because everything is, I assume, being passed by reference when I 
changed the value in one map the corresponding value in all maps changed 
as well.

Andrew Poulos

[toc] | [prev] | [next] | [standalone]


#35229 — Re: using Map

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2018-06-14 14:31 +0200
SubjectRe: using Map
Message-ID<1854071.sLym9PP3UP@PointedEars.de>
In reply to#35228
Andrew Poulos wrote:

> When I then did
> 
> let map2 = new Map(map);
> let map3 = new Map(map);
> let map4 = new Map(map);

First of all, you are confused.  *That* is neither what you did (as posted 
previously; I could not quote it here) nor what I suggested instead (same).

> then because everything is, I assume, being passed by reference

AISB, it is a common misconception that ECMAScript would support
call-by-reference.

> 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?

-- 
PointedEars
FAQ: <http://PointedEars.de/faq> | <http://PointedEars.de/es-matrix>
<https://github.com/PointedEars> | <http://PointedEars.de/wsvn/>
Twitter: @PointedEars2 | Please do not cc me./Bitte keine Kopien per E-Mail.

[toc] | [prev] | [next] | [standalone]


#35230 — Re: using Map

FromAndrew Poulos <ap_prog@hotmail.com>
Date2018-06-14 23:52 +1000
SubjectRe: using Map
Message-ID<RbydnWCQP62s7r_GnZ2dnUU7-bnNnZ2d@westnet.com.au>
In reply to#35229
On 14/06/2018 10:31 PM, Thomas 'PointedEars' Lahn wrote:
> Andrew Poulos wrote:
> 
>> When I then did
>>
>> let map2 = new Map(map);
>> let map3 = new Map(map);
>> let map4 = new Map(map);
> 
> First of all, you are confused.  *That* is neither what you did (as posted
> previously; I could not quote it here) nor what I suggested instead (same).

I tried getting/setting property values in an array of objects.

It was suggested I consider using a Map.

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.

>> then because everything is, I assume, being passed by reference
> 
> AISB, it is a common misconception that ECMAScript would support
> call-by-reference.
> 
>> 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.
When I changed the property value in one of a map's value all the 
corresponding values in the other maps changed as well.

I have looked at the spec but I didn't see anywhere that dealt with 
making copies of a Map. (BTW I find the spec intimidating.)

Andrew Poulos

[toc] | [prev] | [next] | [standalone]


#35233 — Re: using Map

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2018-06-14 17:13 +0200
SubjectRe: using Map
Message-ID<5317938.iMaMEg0OTm@PointedEars.de>
In reply to#35230
Andrew Poulos wrote:

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

,-<http://www.ecma-international.org/ecma-262/8.0/#sec-map-iterable>
| 
| 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: <http://PointedEars.de/faq> | <http://PointedEars.de/es-matrix>
<https://github.com/PointedEars> | <http://PointedEars.de/wsvn/>
Twitter: @PointedEars2 | Please do not cc me./Bitte keine Kopien per E-Mail.

[toc] | [prev] | [next] | [standalone]


#35234 — Re: using Map

From"Mark-" <nospam@mapson.xyz>
Date2018-06-14 16:25 +0000
SubjectRe: using Map
Message-ID<pfu4ua$cfq$1@gioia.aioe.org>
In reply to#35233
Thomas 'PointedEars' Lahn wrote:

> You must learn to control your emotions so that they do not control
> you.

Said the pot.

[toc] | [prev] | [next] | [standalone]


#35232 — Re: using Map

From"Evertjan." <exxjxw.hannivoort@inter.nl.net>
Date2018-06-14 16:11 +0200
SubjectRe: using Map
Message-ID<XnsA901A4B9C12F2eejj99@194.109.6.166>
In reply to#35228
Andrew Poulos <ap_prog@hotmail.com> wrote on 14 Jun 2018 in 
comp.lang.javascript:

> When I then did
> 
> let map2 = new Map(map);
> let map3 = new Map(map);
> let map4 = new Map(map);
> 

Try destructuring:

let map2 = new Map([...map]);

[not tested]

-- 
Evertjan.
The Netherlands.
(Please change the x'es to dots in my emailaddress)

[toc] | [prev] | [next] | [standalone]


#35218

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2018-06-12 16:40 +0100
Message-ID<871sdchv1w.fsf@bsb.me.uk>
In reply to#35214
Andrew Poulos <ap_prog@hotmail.com> writes:

> Say I have an array like this
>
> var objArray = [
>     { id:0, name:'Jonah',   otherProp:321 },
>     { id:1, name:'Andrew',  otherProp:648 },
>     { id:2, name:'Another', otherProp:850 },
>     { id:3, name:'Quite',   otherProp:146 },
>     { id:4, name:'Mary',    otherProp:984 }
> ];
>
> except that the objects have many more properties and the array has
> many more elements.
>
>
> To get, say the 'name' value for the object with an id = 3 I'm using:
>
> var val = objArray.find(function(obj) {
>   return (obj.id === 3 ? obj.name : false);
> });

That's a bit odd. Maybe you meant

var val = objArray.find(function(obj) { return obj.id === 3; }).name;

The return from the function passed to Array.prototype.find is simly
used as a truth value.  Returning obj.name might be deliberate (you'd
pass over elements with a matching is but a name that is "falsey") but
the wording suggests you think you might be getting the name returned
from find.

> And to set the 'name' value for the object with an id = 3 I'm using:
>
> var ind = objArray.findIndex(function(obj) {
>   return obj.id === 3;
> });
>
> objArray[ind]['name'] = "Fred";
>
>
> It works but I'm wondering if someone could show a "better" way.

You don't need the index since objects are shared by reference in
ECMAScript so you could base both of these operations on a function that
returns (a reference to) the object:

function oid(id)
{
    return objArray.find(function(obj) { return obj.id === id; });
}

(though you may want to parameterise it with the array as well).  With
this, oid(3).name is the name and oid(3).name = "Fred" sets the name.

If you do a great many look-ups, it might pay to make an "index" object.
If the IDs are always small integers, this could be an array, but in
general it might need to be an object with non-numeric properties.
Essentially you build an array where idx[3] is a reference to the object
with id === 3.  If the original array changes the id to object mapping,
this index array needs to be temporary, or you must find a way to keep
it synchronised with the original.

(This post got delayed.  I finished it anyway, but I bet you've had all
the answers you need already.)

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#35220

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2018-06-13 05:18 +0200
Message-ID<1609990.zEmimHbLjD@PointedEars.de>
In reply to#35218
Ben Bacarisse wrote:

> Andrew Poulos <ap_prog@hotmail.com> writes:
>> And to set the 'name' value for the object with an id = 3 I'm using:
>>
>> var ind = objArray.findIndex(function(obj) {
>>   return obj.id === 3;
>> });
>>
>> objArray[ind]['name'] = "Fred";
>>
>> It works but I'm wondering if someone could show a "better" way.
> 
> You don't need the index since objects are shared by reference in
> ECMAScript

Only in the broadest possible sense.  There is no concept of “share by 
reference” in programming.  The wording probably stems from the idea that 
objects would be “call-by-reference” and other values would be “call-by-
value”, which is a common *misconception* about ECMAScript 
(implementations).  Instead, *all* values are “call-by-value”, but objects’ 
properties can only be accessed through references to objects; so those 
references are the passed values then.  (This is not exclusive to 
ECMAScript.)

Also, this logic is flawed.  One does not need the “id” as index *here* in 
this *particular* example, because the ”id” property value happens to be the 
index of the array element that is the reference to the respective Object 
instance *here*.

> If you do a great many look-ups, it might pay to make an "index" object.

I find that a strange way to name things.  An “index object” would be an 
object that holds information about one index instead, would it not?

> If the IDs are always small integers, this could be an array,

Whereas "small" is from 0 to 2³²−2 (= 4294967294), and “array” is “_Array 
instance_”:

<http://www.ecma-international.org/publications/files/ECMA-ST-ARCH/ECMA-262,
%201st%20edition,%20June%201997.pdf#page=65>
(1997)

through

<http://www.ecma-international.org/ecma-262/8.0/index.html#sec-array-exotic-objects>
(2017).

For Array-like objects with larger indexes, e.g. jsx.array.BigArray can be 
used:

<https://github.com/PointedEars/JSX/blob/master/array.js#L491-L1127>

> Essentially you build an array where idx[3] is a reference to the object
> with id === 3. 

A possibility:

  /* Use “= []” for an Array instance instead */
  let id2objMap = Object.create(null);

  objArray.forEach((el) => {this[el.id] = el}, id2objMap);

  /* true */
  id2objMap[3].id === 3

Corresponding to Array.from(), there should be an Object.from(objArray, …) 
for this:

  if (!(Object.from instanceof Function))
  {
    Object.from = ((iterable, mapping, thisArg) => {
      var result = thisArg || Object.create(null);

      if (typeof mapping == "undefined")
      {
        throw new TypeError("Mapping not specified");
      }

      let mapfn = mapping;
      if (!(mapping instanceof Function))
      {
        mapfn = function (el) { this[el[mapping]] = el; };
      }

      Array.from(iterable).forEach(mapfn, result);

      return result;
    });
  }

  let id2objMap = Object.from(objArray, "id");


BTW,

  mapfn = ((el) => { this[el[mapping]] = el; });

instead does _not_ work.  Because despite the callback being called with 
“result” as the “this” value, “this” in the arrow function will stubbornly 
refer to the global object in non-strict mode, and be “undefined” in strict 
mode.  This is the result of an IMHO bad design decision/oversight that 
unnecessarily severely limits the use-cases of the useful arrow function 
shorthand.

By contrast, the more backwards-compatible, but longer, function expression 
works in both modes there.

> (This post got delayed.  I finished it anyway, but I bet you've had all
> the answers you need already.)

It might have been better then if you had just not posted.  Consider that 
you do not have to save the world alone, especially if you are unsuited to 
do so.

-- 
PointedEars
FAQ: <http://PointedEars.de/faq> | <http://PointedEars.de/es-matrix>
<https://github.com/PointedEars> | <http://PointedEars.de/wsvn/>
Twitter: @PointedEars2 | Please do not cc me./Bitte keine Kopien per E-Mail.

[toc] | [prev] | [next] | [standalone]


#35221

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2018-06-13 05:25 +0200
Message-ID<1754859.yDWCITohsU@PointedEars.de>
In reply to#35220
Thomas 'PointedEars' Lahn wrote:

> Ben Bacarisse wrote:
>> Essentially you build an array where idx[3] is a reference to the object
>> with id === 3.
> 
> A possibility:
> 
>   /* Use “= []” for an Array instance instead */
>   let id2objMap = Object.create(null);
> 
>   objArray.forEach((el) => {this[el.id] = el}, id2objMap);

  objArray.forEach(function (el) { this[el.id] = el; }, id2objMap);
 
or (probably less efficient)

  objArray.forEach((el) => {id2objMap[el.id] = el});

>   /* true */
>   id2objMap[3].id === 3

See the clarification further below for details.
 
-- 
PointedEars
FAQ: <http://PointedEars.de/faq> | <http://PointedEars.de/es-matrix>
<https://github.com/PointedEars> | <http://PointedEars.de/wsvn/>
Twitter: @PointedEars2 | Please do not cc me./Bitte keine Kopien per E-Mail.

[toc] | [prev] | [next] | [standalone]


#35231

FromJulio Di Egidio <julio@diegidio.name>
Date2018-06-14 07:11 -0700
Message-ID<2dff25bc-8d40-416e-99ba-442c66956b65@googlegroups.com>
In reply to#35214
On Tuesday, 12 June 2018 02:50:42 UTC+2, Andrew Poulos  wrote:
> 
> Say I have an array like this
> 
> var objArray = [
>      { id:0, name:'Jonah',   otherProp:321 },
>      { id:1, name:'Andrew',  otherProp:648 },
>      { id:2, name:'Another', otherProp:850 },
>      { id:3, name:'Quite',   otherProp:146 },
>      { id:4, name:'Mary',    otherProp:984 }
> ];
> 
> except that the objects have many more properties and the array has many 
> more elements.
> 
> 
> To get, say the 'name' value for the object with an id = 3 I'm using:
> 
> var val = objArray.find(function(obj) {
>    return (obj.id === 3 ? obj.name : false);
> });
> 
> And to set the 'name' value for the object with an id = 3 I'm using:
> 
> var ind = objArray.findIndex(function(obj) {
>    return obj.id === 3;
> });
> 
> objArray[ind]['name'] = "Fred";
> 
> It works but I'm wondering if someone could show a "better" way.

In JS _objects_ are *already* hash tables, where the property name is the key...

Here is a quick example, can get more fancy but you get the picture:

-----------------------

var data = {
  "1": { id: 1, ... },
  "2": { id: 2, ... },
};

alert(data["1"].id); // -> 1

data["1"].name = "Name1";

alert(data["NOEXISTENT"]); // -> undefined

data["99"] = { id: 99, ... };

alert(JSON.stringify(data["99"])); // -> { id: 99, ... }

--------------------

HTH,

Julio

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.javascript


csiph-web