2

I have an array like this:

[
  32545343: {
    data: [{id: 1}, {id: 2}]
  },
  547347: {
    data: [{id: 1}, {id: 4}]
  },
  95757: {
    data: [{id: 1}, {id: 6}]
  },
]

How can I merge all data array in a single array without duplicating objects with the same id, like this:

[{id: 1}, {id: 2}, {id: 4}, {id: 6}]
3
  • 4
    It is not a valid array structure Commented Mar 19, 2016 at 18:16
  • 1
    That doesn't look like valid syntax to me - you can't define keys on an array, only on an object. Your outermost [ and ] should be a { and }. Commented Mar 19, 2016 at 18:16
  • are you sure, that you have an array? Commented Mar 19, 2016 at 18:18

4 Answers 4

3

Solution with using Set structure

var d = { 32545343: { data: [{ id: 1 }, { id: 2 }] }, 547347: { data: [{ id: 1 }, { id: 4 }] }, 95757: { data: [{ id: 1 }, { id: 6 }] }, };

var set = new Set();

Object.keys(d).forEach(a =>
    d[a].data.forEach(b => set.add(JSON.stringify(b))));

document.write(Array.from(set));

Sign up to request clarification or add additional context in comments.

Comments

0

Assuming, you have an object, then this solution would work with a temoprary object for collecting same object.

var data = { 32545343: { data: [{ id: 1 }, { id: 2 }] }, 547347: { data: [{ id: 1 }, { id: 4 }] }, 95757: { data: [{ id: 1 }, { id: 6 }] } },
    result = function (object) {
        var r = [];
        Object.keys(object).forEach(function (k) {
            object[k].data.forEach(function (a) {
                if (!this[a.id]) {
                    this[a.id] = a;
                    r.push(a);
                }
            }, this);
        }, {});
        return r;
    }(data);

document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');

Comments

0

The question is not correct, you cannot define array like a map: [ x: 1, y:1 ], correct definition:

var a = {
  32545343: {
    data: [{id: 1}, {id: 2}]
  },
  547347: {
    data: [{id: 1}, {id: 4}]
  },
  95757: {
    data: [{id: 1}, {id: 6}]
  }
};

one solution is using a flatmap (one implementation is here: https://gist.github.com/samgiles/762ee337dff48623e729)

Array.prototype.flatMap = function(lambda) { 
    return Array.prototype.concat.apply([], this.map(lambda)); 
};

then you can convert (do not forget a is not an array it is an object!)

var b = Object.keys(a).flatMap(function(key) { return a[key].data; });

// than you can distinct the list:

var result = b.filter(function(element, index, arr) { return arr.slice(index+1).filter(function(e) { return e.id === element.id }).length===0; });
console.log(result);

2 Comments

Sadly this doesn't dedupe the objects (you have 3 objects with id = 1.
I have added a solution to distinct elements by id, using the first occurence of element.
0

You could adopt a functional approach where you pick out unique objects from a flattened array created from each object's data array.

function flatten(arr) {
  return arr.reduce(function (p, c) {
    return p.concat(c);
  }, []);
}

function pluck(obj, key) {
  return Object.keys(obj).map(function (el) {
    return obj[el][key];
  });
}

function unique(arr, key) {
  var ids = [];
  return arr.filter(function (el) {
    if (ids.indexOf(el[key]) === -1) {
      ids.push(el[key]);
      return true;
    }
  });
}

var result = unique(flatten(pluck(obj, 'data')), 'id');

DEMO

Comments

Your Answer

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