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')

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.