Diff Two Arrays - return the symmetric difference of the two arrays
up vote
1
down vote
favorite
This is my challenge using JavaScript -> Compare two arrays and return a new array with any items only found in one of the two given arrays, but not both. In other words, return the symmetric difference of the two arrays.
My code works, but I think that it can be better.
function diffArray(arr1, arr2) {
var newArr = ;
arr1.map(function(val){
arr2.indexOf(val) < 0 ? newArr.push(val) : '';
});
arr2.map(function(val){
arr1.indexOf(val) < 0 ? newArr.push(val) : '';
});
return newArr;
}
diffArray([1, 2, 3, 5, 6, 7], [1, 2, 3, 4, 5]);
What do you think?
javascript algorithm array
add a comment |
up vote
1
down vote
favorite
This is my challenge using JavaScript -> Compare two arrays and return a new array with any items only found in one of the two given arrays, but not both. In other words, return the symmetric difference of the two arrays.
My code works, but I think that it can be better.
function diffArray(arr1, arr2) {
var newArr = ;
arr1.map(function(val){
arr2.indexOf(val) < 0 ? newArr.push(val) : '';
});
arr2.map(function(val){
arr1.indexOf(val) < 0 ? newArr.push(val) : '';
});
return newArr;
}
diffArray([1, 2, 3, 5, 6, 7], [1, 2, 3, 4, 5]);
What do you think?
javascript algorithm array
Array.prototype.filter() is very appropriate for your usage case: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
– michael.zech
Apr 6 '16 at 8:23
add a comment |
up vote
1
down vote
favorite
up vote
1
down vote
favorite
This is my challenge using JavaScript -> Compare two arrays and return a new array with any items only found in one of the two given arrays, but not both. In other words, return the symmetric difference of the two arrays.
My code works, but I think that it can be better.
function diffArray(arr1, arr2) {
var newArr = ;
arr1.map(function(val){
arr2.indexOf(val) < 0 ? newArr.push(val) : '';
});
arr2.map(function(val){
arr1.indexOf(val) < 0 ? newArr.push(val) : '';
});
return newArr;
}
diffArray([1, 2, 3, 5, 6, 7], [1, 2, 3, 4, 5]);
What do you think?
javascript algorithm array
This is my challenge using JavaScript -> Compare two arrays and return a new array with any items only found in one of the two given arrays, but not both. In other words, return the symmetric difference of the two arrays.
My code works, but I think that it can be better.
function diffArray(arr1, arr2) {
var newArr = ;
arr1.map(function(val){
arr2.indexOf(val) < 0 ? newArr.push(val) : '';
});
arr2.map(function(val){
arr1.indexOf(val) < 0 ? newArr.push(val) : '';
});
return newArr;
}
diffArray([1, 2, 3, 5, 6, 7], [1, 2, 3, 4, 5]);
What do you think?
javascript algorithm array
javascript algorithm array
asked Apr 5 '16 at 11:34
Michael Alves
108116
108116
Array.prototype.filter() is very appropriate for your usage case: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
– michael.zech
Apr 6 '16 at 8:23
add a comment |
Array.prototype.filter() is very appropriate for your usage case: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
– michael.zech
Apr 6 '16 at 8:23
Array.prototype.filter() is very appropriate for your usage case: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
– michael.zech
Apr 6 '16 at 8:23
Array.prototype.filter() is very appropriate for your usage case: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
– michael.zech
Apr 6 '16 at 8:23
add a comment |
6 Answers
6
active
oldest
votes
up vote
3
down vote
As for performance: Array.indexOf
in the worse case(element is not there), will have to check all values of the array to check if the value is in it. And doing this for all values of the second array, means O(n * m) where n is the arr1
size and m is the arr2
size. If n = m, we can consider that it takes O(n*n), which is quite expensive. You could improve this by sorting both arrays and doing a smarter check, but even that will have the cost of the sorting, which is O(n * log n) with a good implementation
Having said all that, what you really want is a structure to check if you have seen or not an element that can check it really quick. In javascript, we can use objets to do this. As its native code we don´t really know the complexity of access, but with testing a bit it is clear that it´s much better (in theory access should be O(1) or O(log n))
The pseudo code is like this:
var seen = {}
iterate all map1 values and mark is as seen
iterate all map2 values and unmark if already seen, mark if not
add all seen values to new array
return array
And here is a full fiddle:
function diffArray(arr1, arr2) {
var newArr = ;
arr1.map(function(val) {
arr2.indexOf(val) < 0 ? newArr.push(val) : '';
});
arr2.map(function(val) {
arr1.indexOf(val) < 0 ? newArr.push(val) : '';
});
return newArr;
}
function diffArray2(arr1, arr2) {
seen = {}
var newArr =
arr1.forEach(function(val) {
seen[val] = 1 // we saw it on first array
})
arr2.forEach(function(val) {
if (seen[val] == 1) { // we already saw it on the first one, unmark
seen[val] = false
} else if (seen.hasOwnProperty(seen[val]) == false) { // if we hadnt seen it earlier
seen[val] = 2 // mark with a 2
}
})
for (var val in seen) {
if (seen[val]) { // if its a 1 or a 2, it was unique
newArr.push(val)
}
}
return newArr
}
var arr1 =
var arr2 =
var mx = 10000;
for (var i = 0; i < mx; i++) {
arr1.push(i)
arr2.push(i + Math.round(mx / 2))
}
console.time("diffArray with arrays and .index")
diffArray(arr1, arr2);
console.timeEnd("diffArray with arrays and .index")
console.time("diffArray with object")
diffArray2(arr1, arr2);
console.timeEnd("diffArray with object")
add a comment |
up vote
2
down vote
map
is specifically designed to map a value to another. You're merely looping through the array, not actually mapping. This is best expressed by using forEach
instead.
function diffArray(arr1, arr2) {
var newArr = ;
arr1.forEach(function(val){
if(arr2.indexOf(val) < 0) newArr.push(val);
});
arr2.forEach(function(val){
if(arr1.indexOf(val) < 0) newArr.push(val);
});
return newArr;
}
add a comment |
up vote
1
down vote
This may not be more efficient than juvian's answer, but I think it's a lot cleaner to use Array.prototype.filter
; it's usage, as the name suggests, it to filter elements out of an array, which is exactly what you are trying to do.
function diffArray(a, b) {
return a.filter(function(val) { // reveal the unique values in a
return b.indexOf(val) < 0;
}.concat(b.filter(function(val) { // concat those with the unique values in b
return a.indexOf(val) < 0;
}
}
And, if you want, you could make it even cleaner by extracting the filter
parts to their own functions:
function getUniqueValues(src, other) {
return src.filter(function(val) {
return other.indexOf(val) < 0;
}
}
Then, your main function becomes:
function diffArr(a, b) {
return getUniqueValues(a, b).concat(getUniqueValues(b, a));
}
Again, this may not be more efficient, but it is more idiomatic in that is uses the right built-in JavaScript methods for the job.
Note: it may be more efficient to sort both arrays for faster computing overall:
function diffArr(a, b) {
a.sort();
b.sort();
...
}
add a comment |
up vote
0
down vote
Your best fit for this issue is to use the (relatively) new guy in town : the Set
, that will do the job for you of ignoring duplicate.
Most browsers support it now, and i looked a few jsperf and it is already fast.
The Set
is especially interesting if you have many duplicates.
Edit : i changed my code for the more efficient code of @juvian, thks to him for his update.
function diffArray(arr1, arr2) {
var set1 = new Set(arr1);
var set2 = new Set(arr2);
var arr =
set1.forEach(function(val) {
if (!set2.has(val)) arr.push(val);
});
set2.forEach(function(val) {
if (!set1.has(val)) arr.push(val);
});
return arr;
}
( Notice that if performance matters you'll want to create only once those 4 Set
and only clear()
them before use ).
Always nice to see people taking advantage of new structures! Would recommend some few changes to make it a bit more performant though: jsfiddle.net/hL9hgynq
– juvian
Apr 7 '16 at 15:04
add a comment |
up vote
0
down vote
The function could be one-liner, but maybe not so readable:
function diffArray(arr1, arr2) {
return [...arr1.filter(el => !arr2.includes(el)), ...arr2.filter(el => !arr1.includes(el))]
}
diffArray([1, 2, 3, 5], [1, 2, 3, 4, 5]);
New contributor
add a comment |
up vote
-1
down vote
You can use this array-diff open source component.
Example:
diff([1,2,3], [1,2,3,4,5]) // => [4,5]
It works by concating the two arrays passed and filtering included vals, returning an array representing the difference between the two arrays:
function diff(firstArray: any, secondArray: any): any {
return firstArray.concat(secondArray).filter((val) => {
return !(firstArray.includes(val) && secondArray.includes(val));
});
};
You have presented an alternative solution, but haven't reviewed the code. Please explain your reasoning (how your solution works and how it improves upon the original) so that the author can learn from your thought process.
– Toby Speight
May 23 '17 at 12:17
K. Edited. Does it make more sense now?
– Yoni
May 23 '17 at 12:25
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
return StackExchange.using("mathjaxEditing", function () {
StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
});
});
}, "mathjax-editing");
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "196"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f124825%2fdiff-two-arrays-return-the-symmetric-difference-of-the-two-arrays%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
6 Answers
6
active
oldest
votes
6 Answers
6
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
3
down vote
As for performance: Array.indexOf
in the worse case(element is not there), will have to check all values of the array to check if the value is in it. And doing this for all values of the second array, means O(n * m) where n is the arr1
size and m is the arr2
size. If n = m, we can consider that it takes O(n*n), which is quite expensive. You could improve this by sorting both arrays and doing a smarter check, but even that will have the cost of the sorting, which is O(n * log n) with a good implementation
Having said all that, what you really want is a structure to check if you have seen or not an element that can check it really quick. In javascript, we can use objets to do this. As its native code we don´t really know the complexity of access, but with testing a bit it is clear that it´s much better (in theory access should be O(1) or O(log n))
The pseudo code is like this:
var seen = {}
iterate all map1 values and mark is as seen
iterate all map2 values and unmark if already seen, mark if not
add all seen values to new array
return array
And here is a full fiddle:
function diffArray(arr1, arr2) {
var newArr = ;
arr1.map(function(val) {
arr2.indexOf(val) < 0 ? newArr.push(val) : '';
});
arr2.map(function(val) {
arr1.indexOf(val) < 0 ? newArr.push(val) : '';
});
return newArr;
}
function diffArray2(arr1, arr2) {
seen = {}
var newArr =
arr1.forEach(function(val) {
seen[val] = 1 // we saw it on first array
})
arr2.forEach(function(val) {
if (seen[val] == 1) { // we already saw it on the first one, unmark
seen[val] = false
} else if (seen.hasOwnProperty(seen[val]) == false) { // if we hadnt seen it earlier
seen[val] = 2 // mark with a 2
}
})
for (var val in seen) {
if (seen[val]) { // if its a 1 or a 2, it was unique
newArr.push(val)
}
}
return newArr
}
var arr1 =
var arr2 =
var mx = 10000;
for (var i = 0; i < mx; i++) {
arr1.push(i)
arr2.push(i + Math.round(mx / 2))
}
console.time("diffArray with arrays and .index")
diffArray(arr1, arr2);
console.timeEnd("diffArray with arrays and .index")
console.time("diffArray with object")
diffArray2(arr1, arr2);
console.timeEnd("diffArray with object")
add a comment |
up vote
3
down vote
As for performance: Array.indexOf
in the worse case(element is not there), will have to check all values of the array to check if the value is in it. And doing this for all values of the second array, means O(n * m) where n is the arr1
size and m is the arr2
size. If n = m, we can consider that it takes O(n*n), which is quite expensive. You could improve this by sorting both arrays and doing a smarter check, but even that will have the cost of the sorting, which is O(n * log n) with a good implementation
Having said all that, what you really want is a structure to check if you have seen or not an element that can check it really quick. In javascript, we can use objets to do this. As its native code we don´t really know the complexity of access, but with testing a bit it is clear that it´s much better (in theory access should be O(1) or O(log n))
The pseudo code is like this:
var seen = {}
iterate all map1 values and mark is as seen
iterate all map2 values and unmark if already seen, mark if not
add all seen values to new array
return array
And here is a full fiddle:
function diffArray(arr1, arr2) {
var newArr = ;
arr1.map(function(val) {
arr2.indexOf(val) < 0 ? newArr.push(val) : '';
});
arr2.map(function(val) {
arr1.indexOf(val) < 0 ? newArr.push(val) : '';
});
return newArr;
}
function diffArray2(arr1, arr2) {
seen = {}
var newArr =
arr1.forEach(function(val) {
seen[val] = 1 // we saw it on first array
})
arr2.forEach(function(val) {
if (seen[val] == 1) { // we already saw it on the first one, unmark
seen[val] = false
} else if (seen.hasOwnProperty(seen[val]) == false) { // if we hadnt seen it earlier
seen[val] = 2 // mark with a 2
}
})
for (var val in seen) {
if (seen[val]) { // if its a 1 or a 2, it was unique
newArr.push(val)
}
}
return newArr
}
var arr1 =
var arr2 =
var mx = 10000;
for (var i = 0; i < mx; i++) {
arr1.push(i)
arr2.push(i + Math.round(mx / 2))
}
console.time("diffArray with arrays and .index")
diffArray(arr1, arr2);
console.timeEnd("diffArray with arrays and .index")
console.time("diffArray with object")
diffArray2(arr1, arr2);
console.timeEnd("diffArray with object")
add a comment |
up vote
3
down vote
up vote
3
down vote
As for performance: Array.indexOf
in the worse case(element is not there), will have to check all values of the array to check if the value is in it. And doing this for all values of the second array, means O(n * m) where n is the arr1
size and m is the arr2
size. If n = m, we can consider that it takes O(n*n), which is quite expensive. You could improve this by sorting both arrays and doing a smarter check, but even that will have the cost of the sorting, which is O(n * log n) with a good implementation
Having said all that, what you really want is a structure to check if you have seen or not an element that can check it really quick. In javascript, we can use objets to do this. As its native code we don´t really know the complexity of access, but with testing a bit it is clear that it´s much better (in theory access should be O(1) or O(log n))
The pseudo code is like this:
var seen = {}
iterate all map1 values and mark is as seen
iterate all map2 values and unmark if already seen, mark if not
add all seen values to new array
return array
And here is a full fiddle:
function diffArray(arr1, arr2) {
var newArr = ;
arr1.map(function(val) {
arr2.indexOf(val) < 0 ? newArr.push(val) : '';
});
arr2.map(function(val) {
arr1.indexOf(val) < 0 ? newArr.push(val) : '';
});
return newArr;
}
function diffArray2(arr1, arr2) {
seen = {}
var newArr =
arr1.forEach(function(val) {
seen[val] = 1 // we saw it on first array
})
arr2.forEach(function(val) {
if (seen[val] == 1) { // we already saw it on the first one, unmark
seen[val] = false
} else if (seen.hasOwnProperty(seen[val]) == false) { // if we hadnt seen it earlier
seen[val] = 2 // mark with a 2
}
})
for (var val in seen) {
if (seen[val]) { // if its a 1 or a 2, it was unique
newArr.push(val)
}
}
return newArr
}
var arr1 =
var arr2 =
var mx = 10000;
for (var i = 0; i < mx; i++) {
arr1.push(i)
arr2.push(i + Math.round(mx / 2))
}
console.time("diffArray with arrays and .index")
diffArray(arr1, arr2);
console.timeEnd("diffArray with arrays and .index")
console.time("diffArray with object")
diffArray2(arr1, arr2);
console.timeEnd("diffArray with object")
As for performance: Array.indexOf
in the worse case(element is not there), will have to check all values of the array to check if the value is in it. And doing this for all values of the second array, means O(n * m) where n is the arr1
size and m is the arr2
size. If n = m, we can consider that it takes O(n*n), which is quite expensive. You could improve this by sorting both arrays and doing a smarter check, but even that will have the cost of the sorting, which is O(n * log n) with a good implementation
Having said all that, what you really want is a structure to check if you have seen or not an element that can check it really quick. In javascript, we can use objets to do this. As its native code we don´t really know the complexity of access, but with testing a bit it is clear that it´s much better (in theory access should be O(1) or O(log n))
The pseudo code is like this:
var seen = {}
iterate all map1 values and mark is as seen
iterate all map2 values and unmark if already seen, mark if not
add all seen values to new array
return array
And here is a full fiddle:
function diffArray(arr1, arr2) {
var newArr = ;
arr1.map(function(val) {
arr2.indexOf(val) < 0 ? newArr.push(val) : '';
});
arr2.map(function(val) {
arr1.indexOf(val) < 0 ? newArr.push(val) : '';
});
return newArr;
}
function diffArray2(arr1, arr2) {
seen = {}
var newArr =
arr1.forEach(function(val) {
seen[val] = 1 // we saw it on first array
})
arr2.forEach(function(val) {
if (seen[val] == 1) { // we already saw it on the first one, unmark
seen[val] = false
} else if (seen.hasOwnProperty(seen[val]) == false) { // if we hadnt seen it earlier
seen[val] = 2 // mark with a 2
}
})
for (var val in seen) {
if (seen[val]) { // if its a 1 or a 2, it was unique
newArr.push(val)
}
}
return newArr
}
var arr1 =
var arr2 =
var mx = 10000;
for (var i = 0; i < mx; i++) {
arr1.push(i)
arr2.push(i + Math.round(mx / 2))
}
console.time("diffArray with arrays and .index")
diffArray(arr1, arr2);
console.timeEnd("diffArray with arrays and .index")
console.time("diffArray with object")
diffArray2(arr1, arr2);
console.timeEnd("diffArray with object")
function diffArray(arr1, arr2) {
var newArr = ;
arr1.map(function(val) {
arr2.indexOf(val) < 0 ? newArr.push(val) : '';
});
arr2.map(function(val) {
arr1.indexOf(val) < 0 ? newArr.push(val) : '';
});
return newArr;
}
function diffArray2(arr1, arr2) {
seen = {}
var newArr =
arr1.forEach(function(val) {
seen[val] = 1 // we saw it on first array
})
arr2.forEach(function(val) {
if (seen[val] == 1) { // we already saw it on the first one, unmark
seen[val] = false
} else if (seen.hasOwnProperty(seen[val]) == false) { // if we hadnt seen it earlier
seen[val] = 2 // mark with a 2
}
})
for (var val in seen) {
if (seen[val]) { // if its a 1 or a 2, it was unique
newArr.push(val)
}
}
return newArr
}
var arr1 =
var arr2 =
var mx = 10000;
for (var i = 0; i < mx; i++) {
arr1.push(i)
arr2.push(i + Math.round(mx / 2))
}
console.time("diffArray with arrays and .index")
diffArray(arr1, arr2);
console.timeEnd("diffArray with arrays and .index")
console.time("diffArray with object")
diffArray2(arr1, arr2);
console.timeEnd("diffArray with object")
function diffArray(arr1, arr2) {
var newArr = ;
arr1.map(function(val) {
arr2.indexOf(val) < 0 ? newArr.push(val) : '';
});
arr2.map(function(val) {
arr1.indexOf(val) < 0 ? newArr.push(val) : '';
});
return newArr;
}
function diffArray2(arr1, arr2) {
seen = {}
var newArr =
arr1.forEach(function(val) {
seen[val] = 1 // we saw it on first array
})
arr2.forEach(function(val) {
if (seen[val] == 1) { // we already saw it on the first one, unmark
seen[val] = false
} else if (seen.hasOwnProperty(seen[val]) == false) { // if we hadnt seen it earlier
seen[val] = 2 // mark with a 2
}
})
for (var val in seen) {
if (seen[val]) { // if its a 1 or a 2, it was unique
newArr.push(val)
}
}
return newArr
}
var arr1 =
var arr2 =
var mx = 10000;
for (var i = 0; i < mx; i++) {
arr1.push(i)
arr2.push(i + Math.round(mx / 2))
}
console.time("diffArray with arrays and .index")
diffArray(arr1, arr2);
console.timeEnd("diffArray with arrays and .index")
console.time("diffArray with object")
diffArray2(arr1, arr2);
console.timeEnd("diffArray with object")
edited Apr 7 '16 at 15:13
answered Apr 5 '16 at 17:50
juvian
87848
87848
add a comment |
add a comment |
up vote
2
down vote
map
is specifically designed to map a value to another. You're merely looping through the array, not actually mapping. This is best expressed by using forEach
instead.
function diffArray(arr1, arr2) {
var newArr = ;
arr1.forEach(function(val){
if(arr2.indexOf(val) < 0) newArr.push(val);
});
arr2.forEach(function(val){
if(arr1.indexOf(val) < 0) newArr.push(val);
});
return newArr;
}
add a comment |
up vote
2
down vote
map
is specifically designed to map a value to another. You're merely looping through the array, not actually mapping. This is best expressed by using forEach
instead.
function diffArray(arr1, arr2) {
var newArr = ;
arr1.forEach(function(val){
if(arr2.indexOf(val) < 0) newArr.push(val);
});
arr2.forEach(function(val){
if(arr1.indexOf(val) < 0) newArr.push(val);
});
return newArr;
}
add a comment |
up vote
2
down vote
up vote
2
down vote
map
is specifically designed to map a value to another. You're merely looping through the array, not actually mapping. This is best expressed by using forEach
instead.
function diffArray(arr1, arr2) {
var newArr = ;
arr1.forEach(function(val){
if(arr2.indexOf(val) < 0) newArr.push(val);
});
arr2.forEach(function(val){
if(arr1.indexOf(val) < 0) newArr.push(val);
});
return newArr;
}
map
is specifically designed to map a value to another. You're merely looping through the array, not actually mapping. This is best expressed by using forEach
instead.
function diffArray(arr1, arr2) {
var newArr = ;
arr1.forEach(function(val){
if(arr2.indexOf(val) < 0) newArr.push(val);
});
arr2.forEach(function(val){
if(arr1.indexOf(val) < 0) newArr.push(val);
});
return newArr;
}
answered Apr 5 '16 at 17:33
Joseph
22.4k21835
22.4k21835
add a comment |
add a comment |
up vote
1
down vote
This may not be more efficient than juvian's answer, but I think it's a lot cleaner to use Array.prototype.filter
; it's usage, as the name suggests, it to filter elements out of an array, which is exactly what you are trying to do.
function diffArray(a, b) {
return a.filter(function(val) { // reveal the unique values in a
return b.indexOf(val) < 0;
}.concat(b.filter(function(val) { // concat those with the unique values in b
return a.indexOf(val) < 0;
}
}
And, if you want, you could make it even cleaner by extracting the filter
parts to their own functions:
function getUniqueValues(src, other) {
return src.filter(function(val) {
return other.indexOf(val) < 0;
}
}
Then, your main function becomes:
function diffArr(a, b) {
return getUniqueValues(a, b).concat(getUniqueValues(b, a));
}
Again, this may not be more efficient, but it is more idiomatic in that is uses the right built-in JavaScript methods for the job.
Note: it may be more efficient to sort both arrays for faster computing overall:
function diffArr(a, b) {
a.sort();
b.sort();
...
}
add a comment |
up vote
1
down vote
This may not be more efficient than juvian's answer, but I think it's a lot cleaner to use Array.prototype.filter
; it's usage, as the name suggests, it to filter elements out of an array, which is exactly what you are trying to do.
function diffArray(a, b) {
return a.filter(function(val) { // reveal the unique values in a
return b.indexOf(val) < 0;
}.concat(b.filter(function(val) { // concat those with the unique values in b
return a.indexOf(val) < 0;
}
}
And, if you want, you could make it even cleaner by extracting the filter
parts to their own functions:
function getUniqueValues(src, other) {
return src.filter(function(val) {
return other.indexOf(val) < 0;
}
}
Then, your main function becomes:
function diffArr(a, b) {
return getUniqueValues(a, b).concat(getUniqueValues(b, a));
}
Again, this may not be more efficient, but it is more idiomatic in that is uses the right built-in JavaScript methods for the job.
Note: it may be more efficient to sort both arrays for faster computing overall:
function diffArr(a, b) {
a.sort();
b.sort();
...
}
add a comment |
up vote
1
down vote
up vote
1
down vote
This may not be more efficient than juvian's answer, but I think it's a lot cleaner to use Array.prototype.filter
; it's usage, as the name suggests, it to filter elements out of an array, which is exactly what you are trying to do.
function diffArray(a, b) {
return a.filter(function(val) { // reveal the unique values in a
return b.indexOf(val) < 0;
}.concat(b.filter(function(val) { // concat those with the unique values in b
return a.indexOf(val) < 0;
}
}
And, if you want, you could make it even cleaner by extracting the filter
parts to their own functions:
function getUniqueValues(src, other) {
return src.filter(function(val) {
return other.indexOf(val) < 0;
}
}
Then, your main function becomes:
function diffArr(a, b) {
return getUniqueValues(a, b).concat(getUniqueValues(b, a));
}
Again, this may not be more efficient, but it is more idiomatic in that is uses the right built-in JavaScript methods for the job.
Note: it may be more efficient to sort both arrays for faster computing overall:
function diffArr(a, b) {
a.sort();
b.sort();
...
}
This may not be more efficient than juvian's answer, but I think it's a lot cleaner to use Array.prototype.filter
; it's usage, as the name suggests, it to filter elements out of an array, which is exactly what you are trying to do.
function diffArray(a, b) {
return a.filter(function(val) { // reveal the unique values in a
return b.indexOf(val) < 0;
}.concat(b.filter(function(val) { // concat those with the unique values in b
return a.indexOf(val) < 0;
}
}
And, if you want, you could make it even cleaner by extracting the filter
parts to their own functions:
function getUniqueValues(src, other) {
return src.filter(function(val) {
return other.indexOf(val) < 0;
}
}
Then, your main function becomes:
function diffArr(a, b) {
return getUniqueValues(a, b).concat(getUniqueValues(b, a));
}
Again, this may not be more efficient, but it is more idiomatic in that is uses the right built-in JavaScript methods for the job.
Note: it may be more efficient to sort both arrays for faster computing overall:
function diffArr(a, b) {
a.sort();
b.sort();
...
}
answered Apr 6 '16 at 21:57
SirPython
11.9k32890
11.9k32890
add a comment |
add a comment |
up vote
0
down vote
Your best fit for this issue is to use the (relatively) new guy in town : the Set
, that will do the job for you of ignoring duplicate.
Most browsers support it now, and i looked a few jsperf and it is already fast.
The Set
is especially interesting if you have many duplicates.
Edit : i changed my code for the more efficient code of @juvian, thks to him for his update.
function diffArray(arr1, arr2) {
var set1 = new Set(arr1);
var set2 = new Set(arr2);
var arr =
set1.forEach(function(val) {
if (!set2.has(val)) arr.push(val);
});
set2.forEach(function(val) {
if (!set1.has(val)) arr.push(val);
});
return arr;
}
( Notice that if performance matters you'll want to create only once those 4 Set
and only clear()
them before use ).
Always nice to see people taking advantage of new structures! Would recommend some few changes to make it a bit more performant though: jsfiddle.net/hL9hgynq
– juvian
Apr 7 '16 at 15:04
add a comment |
up vote
0
down vote
Your best fit for this issue is to use the (relatively) new guy in town : the Set
, that will do the job for you of ignoring duplicate.
Most browsers support it now, and i looked a few jsperf and it is already fast.
The Set
is especially interesting if you have many duplicates.
Edit : i changed my code for the more efficient code of @juvian, thks to him for his update.
function diffArray(arr1, arr2) {
var set1 = new Set(arr1);
var set2 = new Set(arr2);
var arr =
set1.forEach(function(val) {
if (!set2.has(val)) arr.push(val);
});
set2.forEach(function(val) {
if (!set1.has(val)) arr.push(val);
});
return arr;
}
( Notice that if performance matters you'll want to create only once those 4 Set
and only clear()
them before use ).
Always nice to see people taking advantage of new structures! Would recommend some few changes to make it a bit more performant though: jsfiddle.net/hL9hgynq
– juvian
Apr 7 '16 at 15:04
add a comment |
up vote
0
down vote
up vote
0
down vote
Your best fit for this issue is to use the (relatively) new guy in town : the Set
, that will do the job for you of ignoring duplicate.
Most browsers support it now, and i looked a few jsperf and it is already fast.
The Set
is especially interesting if you have many duplicates.
Edit : i changed my code for the more efficient code of @juvian, thks to him for his update.
function diffArray(arr1, arr2) {
var set1 = new Set(arr1);
var set2 = new Set(arr2);
var arr =
set1.forEach(function(val) {
if (!set2.has(val)) arr.push(val);
});
set2.forEach(function(val) {
if (!set1.has(val)) arr.push(val);
});
return arr;
}
( Notice that if performance matters you'll want to create only once those 4 Set
and only clear()
them before use ).
Your best fit for this issue is to use the (relatively) new guy in town : the Set
, that will do the job for you of ignoring duplicate.
Most browsers support it now, and i looked a few jsperf and it is already fast.
The Set
is especially interesting if you have many duplicates.
Edit : i changed my code for the more efficient code of @juvian, thks to him for his update.
function diffArray(arr1, arr2) {
var set1 = new Set(arr1);
var set2 = new Set(arr2);
var arr =
set1.forEach(function(val) {
if (!set2.has(val)) arr.push(val);
});
set2.forEach(function(val) {
if (!set1.has(val)) arr.push(val);
});
return arr;
}
( Notice that if performance matters you'll want to create only once those 4 Set
and only clear()
them before use ).
edited Apr 8 '16 at 9:29
answered Apr 7 '16 at 9:23
GameAlchemist
53828
53828
Always nice to see people taking advantage of new structures! Would recommend some few changes to make it a bit more performant though: jsfiddle.net/hL9hgynq
– juvian
Apr 7 '16 at 15:04
add a comment |
Always nice to see people taking advantage of new structures! Would recommend some few changes to make it a bit more performant though: jsfiddle.net/hL9hgynq
– juvian
Apr 7 '16 at 15:04
Always nice to see people taking advantage of new structures! Would recommend some few changes to make it a bit more performant though: jsfiddle.net/hL9hgynq
– juvian
Apr 7 '16 at 15:04
Always nice to see people taking advantage of new structures! Would recommend some few changes to make it a bit more performant though: jsfiddle.net/hL9hgynq
– juvian
Apr 7 '16 at 15:04
add a comment |
up vote
0
down vote
The function could be one-liner, but maybe not so readable:
function diffArray(arr1, arr2) {
return [...arr1.filter(el => !arr2.includes(el)), ...arr2.filter(el => !arr1.includes(el))]
}
diffArray([1, 2, 3, 5], [1, 2, 3, 4, 5]);
New contributor
add a comment |
up vote
0
down vote
The function could be one-liner, but maybe not so readable:
function diffArray(arr1, arr2) {
return [...arr1.filter(el => !arr2.includes(el)), ...arr2.filter(el => !arr1.includes(el))]
}
diffArray([1, 2, 3, 5], [1, 2, 3, 4, 5]);
New contributor
add a comment |
up vote
0
down vote
up vote
0
down vote
The function could be one-liner, but maybe not so readable:
function diffArray(arr1, arr2) {
return [...arr1.filter(el => !arr2.includes(el)), ...arr2.filter(el => !arr1.includes(el))]
}
diffArray([1, 2, 3, 5], [1, 2, 3, 4, 5]);
New contributor
The function could be one-liner, but maybe not so readable:
function diffArray(arr1, arr2) {
return [...arr1.filter(el => !arr2.includes(el)), ...arr2.filter(el => !arr1.includes(el))]
}
diffArray([1, 2, 3, 5], [1, 2, 3, 4, 5]);
New contributor
New contributor
answered 1 hour ago
Damjan Pavlica
1012
1012
New contributor
New contributor
add a comment |
add a comment |
up vote
-1
down vote
You can use this array-diff open source component.
Example:
diff([1,2,3], [1,2,3,4,5]) // => [4,5]
It works by concating the two arrays passed and filtering included vals, returning an array representing the difference between the two arrays:
function diff(firstArray: any, secondArray: any): any {
return firstArray.concat(secondArray).filter((val) => {
return !(firstArray.includes(val) && secondArray.includes(val));
});
};
You have presented an alternative solution, but haven't reviewed the code. Please explain your reasoning (how your solution works and how it improves upon the original) so that the author can learn from your thought process.
– Toby Speight
May 23 '17 at 12:17
K. Edited. Does it make more sense now?
– Yoni
May 23 '17 at 12:25
add a comment |
up vote
-1
down vote
You can use this array-diff open source component.
Example:
diff([1,2,3], [1,2,3,4,5]) // => [4,5]
It works by concating the two arrays passed and filtering included vals, returning an array representing the difference between the two arrays:
function diff(firstArray: any, secondArray: any): any {
return firstArray.concat(secondArray).filter((val) => {
return !(firstArray.includes(val) && secondArray.includes(val));
});
};
You have presented an alternative solution, but haven't reviewed the code. Please explain your reasoning (how your solution works and how it improves upon the original) so that the author can learn from your thought process.
– Toby Speight
May 23 '17 at 12:17
K. Edited. Does it make more sense now?
– Yoni
May 23 '17 at 12:25
add a comment |
up vote
-1
down vote
up vote
-1
down vote
You can use this array-diff open source component.
Example:
diff([1,2,3], [1,2,3,4,5]) // => [4,5]
It works by concating the two arrays passed and filtering included vals, returning an array representing the difference between the two arrays:
function diff(firstArray: any, secondArray: any): any {
return firstArray.concat(secondArray).filter((val) => {
return !(firstArray.includes(val) && secondArray.includes(val));
});
};
You can use this array-diff open source component.
Example:
diff([1,2,3], [1,2,3,4,5]) // => [4,5]
It works by concating the two arrays passed and filtering included vals, returning an array representing the difference between the two arrays:
function diff(firstArray: any, secondArray: any): any {
return firstArray.concat(secondArray).filter((val) => {
return !(firstArray.includes(val) && secondArray.includes(val));
});
};
edited May 23 '17 at 12:24
answered May 23 '17 at 8:38
Yoni
992
992
You have presented an alternative solution, but haven't reviewed the code. Please explain your reasoning (how your solution works and how it improves upon the original) so that the author can learn from your thought process.
– Toby Speight
May 23 '17 at 12:17
K. Edited. Does it make more sense now?
– Yoni
May 23 '17 at 12:25
add a comment |
You have presented an alternative solution, but haven't reviewed the code. Please explain your reasoning (how your solution works and how it improves upon the original) so that the author can learn from your thought process.
– Toby Speight
May 23 '17 at 12:17
K. Edited. Does it make more sense now?
– Yoni
May 23 '17 at 12:25
You have presented an alternative solution, but haven't reviewed the code. Please explain your reasoning (how your solution works and how it improves upon the original) so that the author can learn from your thought process.
– Toby Speight
May 23 '17 at 12:17
You have presented an alternative solution, but haven't reviewed the code. Please explain your reasoning (how your solution works and how it improves upon the original) so that the author can learn from your thought process.
– Toby Speight
May 23 '17 at 12:17
K. Edited. Does it make more sense now?
– Yoni
May 23 '17 at 12:25
K. Edited. Does it make more sense now?
– Yoni
May 23 '17 at 12:25
add a comment |
Thanks for contributing an answer to Code Review Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
Use MathJax to format equations. MathJax reference.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f124825%2fdiff-two-arrays-return-the-symmetric-difference-of-the-two-arrays%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Array.prototype.filter() is very appropriate for your usage case: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
– michael.zech
Apr 6 '16 at 8:23