0

I have 2 array of objects:

var parents = [
  { id: 77777, data: {}},
  { id: 88888, data: {}},
  { id: 99999, data: {}}
]


var children = [
  {
    belongTo: 77777,
    data: [
      { id: 111, data: {}},
      { id: 222, data: {}}
    ]},
  {
    belongTo: 99999,
    data: [
      { id: 333, data: {}}
    ]
  }
]

I would like to merge the parents and children into:

var all = [
  { id: 77777, data: {}},
  { id: 111, data: {}},
  { id: 222, data: {}},
  { id: 88888, data: {}},
  { id: 99999, data: {}},
  { id: 333, data: {}}
]

]

I have been trying to use split or merge them together and then flatten but it was always very complicated.

What will be the easiest way to achieve that merge?

My complicated way(which doesn't work):

children.map(function(child) {
  var parentIndex = parents.map(function(x) {return x.id}).indexOf(child.id)

  parents.splice(parentIndex + 1, 0, child.data)
})

[].concat.apply([], parents)
Kocur4d
  • 6,701
  • 8
  • 35
  • 53

3 Answers3

3

You just need some nested loops to get it: http://jsfiddle.net/hpfgqc4m/2/

var parents = [
  { 
    id: 77777,
    data: {}
  },
  { 
    id: 88888,
    data: {}
  },
  { 
    id: 99999,
    data: {}
  }
]


var children = [
  {
    belongTo: 77777,
    data: [{
      id: 111,
      data: {}
    },
    {
      id: 222,
      data: {}
    }]
  },
  {
    belongTo: 99999,
    data: [{
      id: 333,
      data: {}
    }]
  }
]
var all = [];
parents.forEach(function(e, k) {
    all.push(e);
    children.forEach(function(el, key) {
        if (el.belongTo == e.id) {
            el.data.forEach(function(element) {
                all.push(element);            
            });                
        }
    });
});
console.log(all);  
Alexandr Lazarev
  • 12,554
  • 4
  • 38
  • 47
1

Try this

var parents = [{
    id: 77777,
    data: {}
}, {
    id: 88888,
    data: {}
}, {
    id: 99999,
    data: {}
}];

var children = [{
    belongTo: 77777,
    data: [{
        id: 111,
        data: {}
    }, {
        id: 222,
        data: {}
    }]
}, {
    belongTo: 99999,
    data: [{
        id: 333,
        data: {}
    }]
}];

function merge(parents, children) {
  var parentsLen = parents.length,
      childLen = children.length,
      i, j,
      result = [];
  
  for (i = 0; i < parentsLen; i++) { 
    result.push(parents[i]);
    
    for (j = 0; j < childLen; j++) {
      if (parents[i].id === children[j].belongTo) {
        result = result.concat(children[j].data);
      }
    };
  }
  
  return result;
}

console.log(merge(parents, children));

Fix for your version

var parents = [{
    id: 77777,
    data: {}
}, {
    id: 88888,
    data: {}
}, {
    id: 99999,
    data: {}
}];

var children = [{
    belongTo: 77777,
    data: [{
        id: 111,
        data: {}
    }, {
        id: 222,
        data: {}
    }]
}, {
    belongTo: 99999,
    data: [{
        id: 333,
        data: {}
    }]
}];

children.forEach(function(child) {
  var parentIndex = parents.map(function(x) {return x.id}).indexOf(child.id);
  parents.splice(parentIndex + 1, 0, child.data)
})

parents = [].concat.apply([], parents)

console.log(parents);
Oleksandr T.
  • 76,493
  • 17
  • 173
  • 144
  • 2
    Hi sorry, got hold up with something. Yes it works fine, both solution - so thank you guys. I will check later on to see my initial splice way with a bit of es6 sugar would make it more pretty – Kocur4d Nov 09 '15 at 13:16
0

Using Higher Order Functions and a bit of ES6:

let merged = parents.map((parent) => {
  let child = children.filter((child) => child.belongTo == parent.id)
  let data = child.length > 0 ? child[0].data : []
  return [parent].concat(data)
})

console.log([].concat(...merged))

Can this be refactored further?

Kocur4d
  • 6,701
  • 8
  • 35
  • 53