Diff Two Arrays - return the symmetric difference of the two arrays











up vote
1
down vote

favorite
2












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?










share|improve this question






















  • 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















up vote
1
down vote

favorite
2












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?










share|improve this question






















  • 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













up vote
1
down vote

favorite
2









up vote
1
down vote

favorite
2






2





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?










share|improve this question













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






share|improve this question













share|improve this question











share|improve this question




share|improve this question










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


















  • 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










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")








share|improve this answer






























    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;
    }





    share|improve this answer




























      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();
      ...
      }





      share|improve this answer




























        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 ).






        share|improve this answer























        • 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


















        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]);





        share|improve this answer








        New contributor




        Damjan Pavlica is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
        Check out our Code of Conduct.

























          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));
          });
          };





          share|improve this answer























          • 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











          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
          });


          }
          });














          draft saved

          draft discarded


















          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")








          share|improve this answer



























            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")








            share|improve this answer

























              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")








              share|improve this answer














              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")






              share|improve this answer














              share|improve this answer



              share|improve this answer








              edited Apr 7 '16 at 15:13

























              answered Apr 5 '16 at 17:50









              juvian

              87848




              87848
























                  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;
                  }





                  share|improve this answer

























                    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;
                    }





                    share|improve this answer























                      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;
                      }





                      share|improve this answer












                      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;
                      }






                      share|improve this answer












                      share|improve this answer



                      share|improve this answer










                      answered Apr 5 '16 at 17:33









                      Joseph

                      22.4k21835




                      22.4k21835






















                          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();
                          ...
                          }





                          share|improve this answer

























                            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();
                            ...
                            }





                            share|improve this answer























                              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();
                              ...
                              }





                              share|improve this answer












                              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();
                              ...
                              }






                              share|improve this answer












                              share|improve this answer



                              share|improve this answer










                              answered Apr 6 '16 at 21:57









                              SirPython

                              11.9k32890




                              11.9k32890






















                                  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 ).






                                  share|improve this answer























                                  • 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















                                  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 ).






                                  share|improve this answer























                                  • 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













                                  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 ).






                                  share|improve this answer














                                  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 ).







                                  share|improve this answer














                                  share|improve this answer



                                  share|improve this answer








                                  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


















                                  • 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










                                  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]);





                                  share|improve this answer








                                  New contributor




                                  Damjan Pavlica is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                                  Check out our Code of Conduct.






















                                    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]);





                                    share|improve this answer








                                    New contributor




                                    Damjan Pavlica is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                                    Check out our Code of Conduct.




















                                      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]);





                                      share|improve this answer








                                      New contributor




                                      Damjan Pavlica is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                                      Check out our Code of Conduct.









                                      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]);






                                      share|improve this answer








                                      New contributor




                                      Damjan Pavlica is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                                      Check out our Code of Conduct.









                                      share|improve this answer



                                      share|improve this answer






                                      New contributor




                                      Damjan Pavlica is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                                      Check out our Code of Conduct.









                                      answered 1 hour ago









                                      Damjan Pavlica

                                      1012




                                      1012




                                      New contributor




                                      Damjan Pavlica is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                                      Check out our Code of Conduct.





                                      New contributor





                                      Damjan Pavlica is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                                      Check out our Code of Conduct.






                                      Damjan Pavlica is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                                      Check out our Code of Conduct.






















                                          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));
                                          });
                                          };





                                          share|improve this answer























                                          • 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















                                          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));
                                          });
                                          };





                                          share|improve this answer























                                          • 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













                                          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));
                                          });
                                          };





                                          share|improve this answer














                                          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));
                                          });
                                          };






                                          share|improve this answer














                                          share|improve this answer



                                          share|improve this answer








                                          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


















                                          • 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


















                                          draft saved

                                          draft discarded




















































                                          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.




                                          draft saved


                                          draft discarded














                                          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





















































                                          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







                                          Popular posts from this blog

                                          Quarter-circle Tiles

                                          build a pushdown automaton that recognizes the reverse language of a given pushdown automaton?

                                          Mont Emei