# Array.prototype.toObjKey and Array.prototype.toObjFunc

**URL:** <https://es.discourse.group/t/array-prototype-toobjkey-and-array-prototype-toobjfunc/605>\
**Category:** 💡 Ideas\
**Tags:** proposal\
**Created:** [December 31, 2020, 5:11pm UTC](https://es.discourse.group/t/array-prototype-toobjkey-and-array-prototype-toobjfunc/605 "2020-12-31T17:11:08Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![velociwabbit](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/velociwabbit/32/211_2.png) [@velociwabbit](https://es.discourse.group/u/velociwabbit)\
**Post date:** [December 31, 2020, 5:11pm UTC](https://es.discourse.group/t/array-prototype-toobjkey-and-array-prototype-toobjfunc/605/1 "2020-12-31T17:11:08Z")

</div>

I find myself doing this many many times and think that it really belongs as a native function on the Array prototype.

If i want to convert an array of recs into a keyed object of the same recs I do this

```javascript

let ary = [ 
    {id: 'myid1' field1:'abc', field2: 'abc' },
    {id: 'myid1' field1:'abc', field2: 'abc' }  
]
let oAry = ary.reduce((prev,rec)=> ({...prev,[rec.id] : rec}),{})

```

Coverting from an array to an object is as ubiquitous as ++ in ones code. As such it should be part of the language.

To accomplish this I have created these two functions that appear to be natural fits for extension to the Array prototype.

```javascript
 Array.prototype.toObjKey = (ary,key , inOjb={})=> 
      ! ary.length || ! key ? inOjb  
     : ary.reduce((prev,rec,ix)=> ({...prev,[rec[key]] : rec }), inOjb )
 
 Array.prototype.toObjFunc = (ary,func, inOjb={})=> 
      ! ary.length || ! func ? inOjb 
      : ary.reduce((prev,rec,ix)=> ({...prev,... func(rec,ix,ary) }), inOjb )

```

These two Array.prototype proposed additions are a natural extension to "Reduce" type functionality that nearly every javascript REST implementation performs .

Low technical risk, low code bloat, easy to understand. What's not to love?

---

<div class="post-metadata">

**Author:** ![aclaymore](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/aclaymore/32/501_2.png) [@aclaymore](https://es.discourse.group/u/aclaymore)\
**Post date:** [December 31, 2020, 5:51pm UTC](https://es.discourse.group/t/array-prototype-toobjkey-and-array-prototype-toobjfunc/605/2 "2020-12-31T17:51:29Z")

</div>

One way this can already be achieved is using [Object.fromEntries](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/fromEntries)

```javascript
Object.fromEntries(ary.map(o => [o.id, o]))

```

Or using a util like [Lodash keyBy](https://lodash.com/docs/4.17.15#keyBy)

```javascript
_.keyBy(arr, 'id');

```

EDIT:

If a method like this was added I wonder if using a `Map` instead of a plain object would be better as it has support for more key types, rather than just strings.

```javascript
Array.prototype.toMapKey = function(key) {
  let keyGetter = key;
  if (typeof key === 'string') {
    keyGetter = (o) => o[key];
  }
  let map = new Map();
  for (let v of this) {
       map.set(keyGetter(v), v);
  }
  return map;
}

```

```javascript
[
  { 'key': 1, prop2: 'foo' },
  { 'key': 2, prop2: 'bar' },
].toMapKey('key');

// or

[
  { 'key': 1, prop2: 'foo' },
  { 'key': 2, prop2: 'bar' },
].toMapKey(o => o.key);

```

```javascript
// both return Map { 1 => { 'key': 1, prop2: 'foo' }, 2 => { 'key': 2, prop2: 'bar' } }

```

---

<div class="post-metadata">

**Author:** ![velociwabbit](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/velociwabbit/32/211_2.png) [@velociwabbit](https://es.discourse.group/u/velociwabbit)\
**Post date:** [January 1, 2021, 9:25pm UTC](https://es.discourse.group/t/array-prototype-toobjkey-and-array-prototype-toobjfunc/605/3 "2021-01-01T21:25:58Z")

</div>

If toMapKey returns a map instead of an object not sure it is the same result. I like the idea as a separate function but what i am looking for is something that just returns a vanilla javascript object with the right keys. This is the most common use case.

To be perfectly honest I have never found a reason to use map over object. Perhaps it is just my ignorance. (that being said I also only use Set to dedupe arrays :) )

Also Not a big fan of adding lodash to every package.json. Lodash is a great reference to figure out how to do things but adds to complexity and code bloat. On the other hand if there was such thing as a ecma blessed standard template library a la c++ for javascript that was guaranteed to be minimal (and not an extra repo that must be included and maintained) that would be great.

Also like your suggestion about Object.fromEntries ... perfect replacement for the toObjFunc I suggested which is a bit of a ham fisted solution . That being said, converting to and from objects and arrays is at the core of how javascript is used and a "toObjKey" (or "keyBy" per lodash naming) really should be part of the Array prototype.

---

<div class="post-metadata">

**Author:** ![claudiameadows](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/claudiameadows/32/126_2.png) [@claudiameadows](https://es.discourse.group/u/claudiameadows)\
**Post date:** [January 2, 2021, 6:28pm UTC](https://es.discourse.group/t/array-prototype-toobjkey-and-array-prototype-toobjfunc/605/4 "2021-01-02T18:28:06Z")

</div>

I like `Object.fromValues(values, key)` better - and furthermore, this should also be added to `Map` for similar reasons. And yes, I've ran into this a lot myself, though something like `Object.mapValues(...)` would be more immediately useful. (Engines could and should optimize for key uniqueness, though.)

Not sure I see the benefit of accepting a source object when you can just do `Object.assign(target, Object.fromValues(...))` instead.
