7

I try to get all same data values into an array of objects. This is my input:

var a = [{
    name: "Foo",
    id: "123",
    data: ["65d4ze", "65h8914d"]
  },
  {
    name: "Bar",
    id: "321",
    data: ["65d4ze", "894ver81"]
  }
]

I need a result like:

["65d4ze"]

I try to loop on my object to get this output, but I'm completely lost... I don't know how to know if the result is into all data arrays.

var a = [{
        name: "Foo",
        id: "123",
        data: ["65d4ze", "65h8914d"]
      },
      {
        name: "Bar",
        id: "321",
        data: ["65d4ze", "894ver81"]
      }
    ],
  b = [],
  c = []
a.forEach(function(object) {
  b.push(object.data.map(function(val) {
    return val;
    })
  );
});

console.log(b);
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Kamoulox
  • 311
  • 1
  • 3
  • 11
  • So get all arrays elements that are present on all `a`? – Eddie Mar 25 '19 at 10:06
  • 3
    Possible duplicate of [Simplest code for array intersection in javascript](https://stackoverflow.com/questions/1885557/simplest-code-for-array-intersection-in-javascript) – James Long Mar 25 '19 at 10:07
  • @JamesLong I don't understand the duplication, why this answer can help me ? – Kamoulox Mar 25 '19 at 10:08
  • @Eddie I need to get all array into the key data. This key is present into all object of my principal array. – Kamoulox Mar 25 '19 at 10:11
  • @Kamoulox you have 2 arrays (a[0].data and a[1].data). You seem to be wanting an array of all the values that appear in both arrays. Unless I'm mis-reading your question – James Long Mar 25 '19 at 10:12
  • @Kamoulox didn't get this line "I don't know how to know if the result is into all data array.". If you can clarify, then I can help – Himanshu Shekhar Mar 25 '19 at 10:13
  • So it doesnt matter if the array has 2 objects or more than 2 right? Correct me if I were wrong. @Kamoulox – tnkh Mar 25 '19 at 11:06
  • @tnkh Yes and the answer of Nina Scholz give me a perfect way to do that – Kamoulox Mar 25 '19 at 14:37

5 Answers5

12

You could map data and get the common values with Array#map, Array#reduce, Array#filter, Set and Set#has.

var array = [{ name: "Foo", id: "123", data: ["65d4ze", "65h8914d"] }, { name: "Bar", id: "321", data: ["65d4ze", "894ver81"] }],
    key = 'data',
    common = array
        .map(o => o[key])
        .reduce((a, b) => b.filter(Set.prototype.has, new Set(a)));

console.log(common);
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
  • I have some troubles to understand this piece of code `b.filter(Set.prototype.has, new Set(a))`. But it's working perfectly, thanks – Kamoulox Mar 25 '19 at 10:16
  • 5
    `filter` has two parameters, one foir the callback, which is here a prototype function of `Set`, `has` which checks a value against a set. at this point, the method does not works because it need an instance of `Set`. the second parameter is `thisArg`, where you can hand over an object, which is used as `this` in the callback. mabe a different use makes ir a bet more clear. you could gate the same with a bound `this` by using this as callback: `Set.prototype.has.bind(new Set(a))`, which is now a function with `this`. – Nina Scholz Mar 25 '19 at 10:21
  • With array `common = array .map(o => o[key]) .reduce((a, b) => b.filter(Array.prototype.includes, a));` – Pranav C Balan Mar 25 '19 at 10:21
  • @PranavCBalan, [`Array#includes`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes) uses a second parameter `fromIndex` and gets this value with the index of the callback ... – Nina Scholz Mar 25 '19 at 10:24
  • @NinaScholz : oops that's right, that would make issues :) – Pranav C Balan Mar 25 '19 at 10:25
3

You can use the Array#filter method. Filter the first array by checking if a value is present in all other object properties (arrays), using the Array#every method to check if a value is present in all remaining arrays.

let res = a[0].data.filter(v => a.slice(1).every(a => a.data.includes(v)));

var a = [{
    name: "Foo",
    id: "123",
    data: ["65d4ze", "65h8914d"]
  },
  {
    name: "Bar",
    id: "321",
    data: ["65d4ze", "894ver81"]
  }
];

let res = a[0].data.filter(v => a.slice(1).every(a => a.data.includes(v)));

console.log(res)
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Pranav C Balan
  • 113,687
  • 23
  • 165
  • 188
1

var a = [{
      name: "Foo",
      id: "123",
      data: ["65d4ze", "65h8914d"]
    },
    {
      name: "Bar",
      id: "321",
      data: ["65d4ze", "894ver81"]
    }
  ],
  b = {};
a.forEach(function(i) {
  i.data.forEach(function(j) {
    if (!b.hasOwnProperty(j)) {
      b[j] = 0;
    }
    b[j] = b[j] + 1;
  });
});
c = []
for (var i in b) {
  if (b.hasOwnProperty(i)) {
    if (b[i] > 1) {
      c.push(i)
    }
  }
}
console.log(c);
Shrijan Tiwari
  • 673
  • 6
  • 17
1

Use the flat function in the array:

var a = [{
        name: "Foo",
        id: "123",
        data: ["65d4ze", "65h8914d"]
      },
      {
        name: "Bar",
        id: "321",
        data: ["65d4ze", "894ver81"]
      }
    ],
  b = [],
  c = []
a.forEach(function(object) {
  b.push(object.data.map(function(val) {
    return val;
    })
  );
});

console.log(b.flat());
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
thelastworm
  • 544
  • 4
  • 14
1

You could use reduce and concat on each data array, and check the count of each item.

In the end, you check whether all objects across the array contain that item and return it if yes.

Note that this function works if you want to extract the item that has the same occurrence across all objects in the array.

If an item has duplicates, but does not fulfill the above condition, it would not be extracted.

let a = [{name: "Foo",id: "123",data: ["65d4ze", "65h8914d"]},{name: "Bar",id: "321",data: ["65d4ze", "894ver81"]}]

let arr = a.reduce((prev,next) => prev.data.concat(next.data))
let counts = {};
let result = [];
for (var i = 0; i < arr.length; i++) {
  var num = arr[i];
  counts[num] = counts[num] ? counts[num] + 1 : 1;
}

for (let i in counts) {
    if (counts[i] === a.length) {
        result.push(i)
    }
}
console.log(result)
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
tnkh
  • 1,749
  • 2
  • 14
  • 30