DopustimVladimir
DopustimVladimir

Reputation: 174

How to generate Child keys by Parents keys in Array

JavaScript ninjas! Now i have this collection:

var cats = [
    { id: 1, parent_id: 0, title: 'Movies' },
    { id: 2, parent_id: 0, title: 'Music' },
    { id: 3, parent_id: 1, title: 'Russian movies' },
    { id: 4, parent_id: 2, title: 'Russian music' },
    { id: 5, parent_id: 3, title: 'New' },
    { id: 6, parent_id: 3, title: 'Top10' },
    { id: 7, parent_id: 4, title: 'New' },
    { id: 8, parent_id: 4, title: 'Top10' },
    { id: 9, parent_id: 0, title: 'Soft' }
];

And i need this result:

var catsExtended = [
    { id: 1, parent_id: 0, childs: [ 3, 5, 6 ], title: 'Movies' },
    { id: 2, parent_id: 0, childs: [ 4, 7, 8 ], title: 'Music' },
    { id: 3, parent_id: 1, childs: [ 5, 6 ], title: 'Russian movies' },
    { id: 4, parent_id: 2, childs: [ 7, 8 ], title: 'Russian music' },
    { id: 5, parent_id: 3, childs: [], title: 'New' },
    { id: 6, parent_id: 3, childs: [], title: 'Top10' },
    { id: 7, parent_id: 4, childs: [], title: 'New' },
    { id: 8, parent_id: 4, childs: [], title: 'Top10' },
    { id: 9, parent_id: 0, childs: [], title: 'Soft' }
];

Help me pleace to collect all IDs

Upvotes: 2

Views: 348

Answers (3)

Morteza Tourani
Morteza Tourani

Reputation: 3536

I think a simple Array.prototype.forEach can do a lot.

var cats = [{ id: 1, parent_id: 0, title: 'Movies' }, { id: 2, parent_id: 0, title: 'Music' }, { id: 3, parent_id: 1, title: 'Russian movies' }, { id: 4, parent_id: 2, title: 'Russian music' }, { id: 5, parent_id: 3, title: 'New' }, { id: 6, parent_id: 3, title: 'Top10' }, { id: 7, parent_id: 4, title: 'New' }, { id: 8, parent_id: 4, title: 'Top10' }, { id: 9, parent_id: 0, title: 'Soft' }];

cats.forEach(function(c) {
  var pid = c.parent_id;
  c.children = (this[c.id] = this[c.id] || []);
  (this[pid] = (this[pid] || [])).push(c.id)
}, Object.create(null));

console.clear();
console.log(cats);

Upvotes: 0

Nina Scholz
Nina Scholz

Reputation: 386746

You could use a hash table for the reference to the already returned objects. And for the parents just iterate until parent_id becomes zero.

var cats = [{ id: 1, parent_id: 0, title: 'Movies' }, { id: 2, parent_id: 0, title: 'Music' }, { id: 3, parent_id: 1, title: 'Russian movies' }, { id: 4, parent_id: 2, title: 'Russian music' }, { id: 5, parent_id: 3, title: 'New' }, { id: 6, parent_id: 3, title: 'Top10' }, { id: 7, parent_id: 4, title: 'New' }, { id: 8, parent_id: 4, title: 'Top10' }, { id: 9, parent_id: 0, title: 'Soft' }],
    catsExtended = cats.map(function (a) {
        var id = a.parent_id;
        this[a.id] = { id: a.id, parent_id: a.parent_id, children: [], title: a.title };
        while (id) {
            this[id].children.push(a.id);
            id = this[id].parent_id;
        }
        return this[a.id];
    }, Object.create(null));

console.log(catsExtended);

Upvotes: 2

haim770
haim770

Reputation: 49135

Combine map() and filter():

var catsExtended = cats.map(function(cat) {
    return {
      id: cat.id,
      parent_id: cat.parent_id,
      title: cat.title,
      childs: cats.filter(function(c) {
        return c.parent_id == cat.id;
      }).map(function(c) {
        return c.id
      })
    };
});

Upvotes: 1

Related Questions