admin管理员组文章数量:1400148
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]
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]
Share
Improve this question
edited Dec 15, 2018 at 15:27
leonardofed
asked Dec 15, 2018 at 15:24
leonardofedleonardofed
9862 gold badges9 silver badges26 bronze badges
2
-
2
Did you think about using sets instead? Something like this: jsfiddle/briosheje/y03osape/1
Array.from(new Set([...arrays].flat()));
– briosheje Commented Dec 15, 2018 at 15:26 -
1
What does mean union for you? I would expect the result of
[5, 15]
. – kind user Commented Dec 15, 2018 at 15:32
4 Answers
Reset to default 5Just 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 bees an array of arrays) ->[5, 10, 15], [15, 88, 1, 5, 7], [100, 15, 10, 1, 5]
bees:[[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/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flat ->[[5, 10, 15], [15, 88, 1, 5, 7], [100, 15, 10, 1, 5]]
bees[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/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set. ->[5, 10, 15, 15, 88, 1, 5, 7, 100, 15, 10, 1, 5]
bees 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/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 itsthis
and providing our array as the argument:[].concat.apply([],[...arrays])
Snippet: http://jsfiddle/briosheje/y03osape/2/
Snippet without .flat
: http://jsfiddle/briosheje/y03osape/4/
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);
I tried to copy your approach of looping over arrays but in a slightly more efficient manner, using only ES5 safe functions. I'm sure the other answers are more efficient if you can use the features they do.
var a = [1, 2, 3];
var b = [1, 2, 4, 5];
var c = [2, 7, 9];
// takes an array of arrays
function getUnique(input) {
var unique = [];
// loop over each array
input.forEach(function(item) {
// loop over each value
item.forEach(function(value) {
// if it's not already in the unique array,
if (unique.indexOf(value) == -1) {
// add it
unique.push(value);
}
});
});
return unique;
}
// takes an array of arrays
function getIntersection(input) {
// assume all elements in first array are mon
var intersection = input.shift();
var remove = [];
// loop over items in first array and attempt to
// disprove monality
intersection.forEach(function(value) {
// loop over subsequent arrays
for (var i = 0; i < input.length; i++) {
var item = input[i];
// if these arrays don't contain the value,
// then it isn't an intersection
if (item.indexOf(value) == -1) {
// add it to an array to be removed
remove.push(value);
// exit this loop
break;
}
}
});
// remove values determined not to be intersections
remove.forEach(function(value) {
intersection.splice(intersection.indexOf(value), 1);
})
return intersection;
}
var test = getUnique([a, b, c]);
console.log(test);
var test2 = getIntersection([a, b, c]);
console.log(test2);
Based on custom forEach and Reduce from previously in the exercise at http://csbin.io/callbacks
function forEach(array, callback) {
for(i = 0; i < array.length; i++){
callback(array[i])
}
}
function reduce(array, callback, initialValue) {
for(let i of array){
initialValue = callback(initialValue, i)
}
return initialValue
}
function union(...arrays) {
return reduce(arrays, (seen, next) => {
forEach(next, (element) => {
if(!seen.includes(element)) seen.push(element);
})
return seen
}, [])
}
Note if you use the in-built reduce function you can remove the empty inital array requirement.
本文标签: javascriptUnion between three arraysStack Overflow
版权声明:本文标题:javascript - Union between three arrays - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744226446a2596113.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论