0

I'm trying to take this array of objects:

var channels = [{
    cid: 5,
    pid: 10
},
{
    cid: 10,
    pid: 0
},
{
    cid: 20,
    pid: 5
},
{
    cid: 15,
    pid: 10
}];

cid = channel Id, pid = parent channel Id.

I need to group the channels under their parents, however, those channels could also be parents. How can I group them recursively to look like below?:

var data = [{
    cid: 10,
    pid: 0,
    sub_channels: [{
        cid: 5,
        pid: 10,
        sub_channels: [{
            cid: 20,
            pid: 5
        }]
    },
    {
        cid: 15,
        pid: 10
    }];
}];

I'm using NodeJS so I'm very open to trying any modules, or javascript libraries to get this to work.

1 Answer 1

1

Here it is, it only needs 3 loops over the collection.

var _ = require('lodash')

var channels = [
  {
    cid: 5,
    pid: 10
  },
  {
    cid: 10,
    pid: 0
  },
  {
    cid: 20,
    pid: 5
  },
  {
    cid: 15,
    pid: 10
  }
];

var map = {}
  , parented = {}

_(channels)
    .each(function (channel) {
      map[channel.cid] = channel;
    })
    .each(function (channel) {
      var parent = map[channel.pid]
      if (!parent) return
      if (!parent.sub_channels) parent.sub_channels = []

      parent.sub_channels.push(channel)
      parented[channel.cid] = channel
    })

var result = _.filter(map, function (channel) {
  return !parented[channel.cid]
})

console.log(JSON.stringify(result, null, 2))
Sign up to request clarification or add additional context in comments.

2 Comments

Is there a way I can preserve the ordering? The channels with a pid of 0 are ordered by cid, I'd like to keep the order they came in as. Is that possible?
The easiest way would be to just call result = _.sortBy(result, 'cid')

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.