1

Given n-number of collections/arrays, I would like to identify common elements and which collections they are common to.

This is a little bit similar to this question, however there could be similar elements in say, colletion1 and collection3, or even all of them. I am not only looking for elements similar in all collections. In addition I am open to using any Node.js libraries.

var arr["One"] =   arrProps[{name: '1', prop2: 'aaa'}], arrValues['apple', 'orange', 'banana', 'pear', 'fish', 'pancake', 'taco', 'pizza'];
var arr["Two"] =   arrProps[{name: '2', prop2: 'bbb'}], arrValues['taco', 'fish', 'apple', 'pizza', 'car'];
var arr["Three"] = arrProps[{name: '3', prop2: 'ccc'}], arrValues['banana', 'pizza', 'fish', 'apple', 'orange', ];
var arr["Four"] =  arrProps[{name: '4', prop2: 'ddd'}], arrValues['grape', 'pear', 'chicken', 'car', 'orange'];

Result should be:

[arrValue, arrProps.name]
apple: 1,2,3
banana: 1,3
pear: 1,4
fish: 1,2,3
taco:  1,2
pizza: 1,3
car: 2,4
orange: 3,4

Rather than using arrays, if this were represented as a JSON graph, would that be any easier to solve, and if so, how?

isherwood
  • 58,414
  • 16
  • 114
  • 157
ElHaix
  • 12,846
  • 27
  • 115
  • 203

2 Answers2

1

Thanks to @FFire for tackling this.

I have modified the code in order to be able to access object properties and output the result in various tables for visibility.

const arr = [
{ arrProps: [{name: '1', prop2: 'aaa'}], arrValues: ['apple', 'orange', 'banana', 'pear', 'fish', 'pancake', 'taco', 'pizza'] },
{ arrProps: [{name: '2', prop2: 'bbb'}], arrValues: ['taco', 'fish', 'apple', 'pizza', 'car'] },
{ arrProps: [{ name: '3', prop2: 'ccc' }], arrValues: ['banana', 'pizza', 'fish', 'apple', 'orange'] },
{ arrProps: [{ name: '4', prop2: 'ddd' }], arrValues: ['grape', 'pear', 'chicken', 'car', 'orange'] },
{ arrProps: [{ name: '5', prop2: 'ddeeed' }], arrValues: ['blade', 'movie', 'apple', 'banana', 'lake'] }

];

const result = arr
  .flatMap(({ arrValues }) => arrValues )  // all values
  .filter((value, index, coll) => coll.indexOf(value) === index) //unique values
  .reduce((acc, value) => {
    const parentProp = arr      // name, prop2, arrValues
      .filter((obj) => obj.arrValues.includes(value))
      .map((obj) => obj.arrProps[0]);
      
      //acc[value] = (acc[value] ? [...acc[value], parentProp] : [parentProp])
      //.join(',');
      acc[value] = parentProp
      
    return acc;
}, {})


console.log(result);


Object.entries(result).forEach(([k, v]) => {
    //console.log("The pair: ", k)
    ////console.log("The value: ", v)
    //v.forEach(_parent => console.log(`
    //    Name: ${_parent.name}    
    //    Prop: {_parent.prop2}
    //`));
    console.log(`      ----] The value '${k}' exists in:`);
    console.table(v);
})

console.table(result);

//result["apple"].forEach(e => console.log(e.name));

console.log(JSON.stringify(result));

enter image description here

enter image description here

Of course, like all solutions, there may be a more efficient way of doing this. More responses welcome.

ElHaix
  • 12,846
  • 27
  • 115
  • 203
0

Kind of 'dumb' solution:

const arr = [
{ arrProps: [{name: '1', prop2: 'aaa'}], arrValues: ['apple', 'orange', 'banana', 'pear', 'fish', 'pancake', 'taco', 'pizza'] },
{ arrProps: [{name: '2', prop2: 'bbb'}], arrValues: ['taco', 'fish', 'apple', 'pizza', 'car'] },
{ arrProps: [{name: '3', prop2: 'ccc'}], arrValues: ['banana', 'pizza', 'fish', 'apple', 'orange' ] },
{ arrProps: [{name: '4', prop2: 'ddd'}], arrValues: ['grape', 'pear', 'chicken', 'car', 'orange'] }
];

const result = arr
  .flatMap(({ arrValues }) => arrValues )  // all values
  .filter((value, index, coll) => coll.indexOf(value) === index) //unique values
  .reduce((acc, value) => {
    const propName = arr
      .filter((obj) => obj.arrValues.includes(value))
      .map((obj) => obj.arrProps[0].name);
      
    acc[value] = (acc[value] ? [...acc[value], propName] : [propName])
      .join(',');
      
    return acc;
}, {})

console.log(result)
.as-console-wrapper { max-height: 100% !important; top: 0; }

update

I reconsidered my approach to solution and realized it was fundamentally wrong.

updated solution:

const arr = [
{ arrProps: [{name: '1', prop2: 'aaa'}], arrValues: ['apple', 'orange', 'banana', 'pear', 'fish', 'pancake', 'taco', 'pizza'] },
{ arrProps: [{name: '2', prop2: 'bbb'}], arrValues: ['taco', 'fish', 'apple', 'pizza', 'car'] },
{ arrProps: [{name: '3', prop2: 'ccc'}], arrValues: ['banana', 'pizza', 'fish', 'apple', 'orange' ] },
{ arrProps: [{name: '4', prop2: 'ddd'}], arrValues: ['grape', 'pear', 'chicken', 'car', 'orange'] }
];

const result = arr.reduce((acc, { arrProps: [{ name }], arrValues }) => {
    arrValues.forEach((value) => {
         acc[value] = acc[value] ? `${acc[value]},${name}`: name;
    });     
    return acc;
}, {});

console.log(result)
.as-console-wrapper { max-height: 100% !important; top: 0; }
A1exandr Belan
  • 4,442
  • 3
  • 26
  • 48
  • @ElHaix While I believe your intentions are honorable, trying to "cancel" other people's votes ***actively harms all of Stack Overflow***. Folks don't provide reasons for downvotes because of all the harrasment thrown at them when they do, and also because **it is not a requirement**. The downvote arrows already specify the reasons one would downvote. Please don't do that. Two wrong things don't make a right one. – Félix Adriyel Gagnon-Grenier Dec 23 '21 at 05:41
  • @ElHaix I reconsidered my approach to solution and realized it was fundamentally wrong. Added an updated solution. – A1exandr Belan Dec 23 '21 at 07:34