Building objects in javascript, without "if(!a[k]) a[k] = []" When building objects using reduce, I often have crappy code like this:

function mapArticlesByTagAndId(articles) {
    return articles.reduce((collector = {}, article) =&gt; {
        const { tag, id } = article;
        if(!collector[tag]) collector[tag] = {};

        collector[tag][id] = article;
        return collector;
    })
}


I would love to one line this, but I can't figure out a way to do it.
If only assigning a property to undefined created an object =P [Obviously this would cause different problems haha]
Here's one variant which gets rid of the explicit if at the cost of potential useless reassignment. This, however, does not take away the necessity of ensuring that the k key has a collection object in place...

const result =
  myArr.reduce((collector, { k, j, v }) =&gt; {
    collector[k] = collector[k] || [];
    collector[k][j] = v;
    return collector;
  }, {});


Assuming, ES6 syntax is fine with you, here's another variant. Please notice that it the spread operator (... will result in copying the ...collector[k] item-by-item). I.e. this is less performant and may be an issue for large objects.

const result =
  myArr.reduce((collector, { k, j, v }) =&gt; {
   collector[k] = collector[k] ? [...collector[k], v] : [ v ];
   return collector;
  }, {});


which may be compacted further:

const result =
  myArr.reduce((collector, { k, j, v }) =&gt;
    (collector[k] = collector[k] ? [...collector[k], v] : [ v ], collector),
    {});


Update 1

const result =
  myArr.reduce((collector, { k, j, v }) =&gt;
    (collector[k] = !collector[k] ? [v] : (collector[k].push(v), collector[k])),
    {});