Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Union between three arrays

I need to find the union of three arrays that get passed to the function union.

It took me about 50lines to code to get the expected result. Apparently, the following code works but now I wonder what are the best ways (either in a functional and in a non-functional fashion) to do the same job.

function union(...arrays) {
    var array1 = arguments[0];
    var array2 = arguments[1];
    var array3 = arguments[2];      

    var unique = [];
    var intersaction = [];

    // find the unique values

    for(let i = 0; i < array1.length; i++) {
        if( (array2.includes(array1[i]) == false) && (array3.includes(array1[i])) == false ) {
            unique.push(array1[i]); 
        }
    }

    for(let i = 0; i < array2.length; i++) {
        if( (array1.includes(array2[i]) == false) && (array3.includes(array2[i])) == false ) {
            unique.push(array2[i]); 
        }
    }

    for(let i = 0; i < array3.length; i++) {
        if( (array1.includes(array3[i]) == false) && (array2.includes(array3[i])) == false ) {
            unique.push(array3[i]);
        }
    }

    // find the intersection

    for(let j = 0; j < array1.length; j++) {
        if(array2.includes(array1[j]) || array3.includes(array1[j]) ) {
            if (intersaction.indexOf(array1[j]) == -1) { 
                intersaction.push(array1[j]);
            }
        }
    }

    for(let j = 0; j < array2.length; j++) {
        if(array1.includes(array2[j]) || array3.includes(array2[j]) ) {
            if (intersaction.indexOf(array2[j]) == -1) { 
                    intersaction.push(array2[j]);
            }       
        }
    }

    for(let j = 0; j < array3.length; j++) {
        if(array1.includes(array3[j]) || array2.includes(array3[j]) ) {
            if (intersaction.indexOf(array3[j]) == -1) { 
                    intersaction.push(array3[j]);
            }       
        }
    }

    return union = [...intersaction, ...unique];

}

console.log(union([5, 10, 15], [15, 88, 1, 5, 7], [100, 15, 10, 1, 5]));
// should log: [5, 10, 15, 88, 1, 7, 100]
like image 458
leonardofed Avatar asked Dec 17 '22 19:12

leonardofed


2 Answers

Just another solution keeping the original function signature provided by the OP:

function union(...arrays) {
    return Array.from(new Set([...arrays].flat()));
}

console.log(union([5, 10, 15], [15, 88, 1, 5, 7], [100, 15, 10, 1, 5]));

Or, even shorter (but less read friendly):

return [...(new Set([...arrays].flat()))];

Explanation:

  • Array.from takes an Iterable as an argument, this will create a new array from the original one.
  • [...arrays] spreads the arrays (argument) into a new, single, one (So it becomes an array of arrays) -> [5, 10, 15], [15, 88, 1, 5, 7], [100, 15, 10, 1, 5] becomes: [[5, 10, 15], [15, 88, 1, 5, 7], [100, 15, 10, 1, 5]]
  • .flat flattens the array, making that an array of values rather than ar array of arrays of values -> https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flat -> [[5, 10, 15], [15, 88, 1, 5, 7], [100, 15, 10, 1, 5]] becomes [5, 10, 15, 15, 88, 1, 5, 7, 100, 15, 10, 1, 5]
  • new Set removes duplicates from the array and returns an Iterable https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set. -> [5, 10, 15, 15, 88, 1, 5, 7, 100, 15, 10, 1, 5] becomes a Set instance (an Iterable) without the duplicates. Array.from then converts the Set (Iterable) to a regular array. Further infos here: How to convert Set to Array?

BEWARE: Array.flat is currently an experimental feature (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flat). Solution without using flat below:

function union(...arrays) {
    return Array.from(new Set([].concat.apply([],[...arrays])));
}

console.log(union([5, 10, 15], [15, 88, 1, 5, 7], [100, 15, 10, 1, 5]));

Explanation (only differences from above):

  • Instead of .flat, we apply to Array.concat our original array, so that it will flatten it passing a new array as its this and providing our array as the argument: [].concat.apply([],[...arrays])

Snippet: http://jsfiddle.net/briosheje/y03osape/2/

Snippet without .flat: http://jsfiddle.net/briosheje/y03osape/4/

like image 60
briosheje Avatar answered Feb 08 '23 10:02

briosheje


use set that's very simple,

The Set object lets you store unique values of any type, whether primitive values or object

var a=  [5, 10, 15];
var b=[15, 88, 1, 5, 7];
var c=[100, 15, 10, 1, 5];
var result= [...new Set([...a, ...b,...c])];
console.log(result);
like image 20
Just code Avatar answered Feb 08 '23 09:02

Just code