1

OBJECTIVE

I am trying to highlight the dfferences between two arrays. Please note that arr1 and arr2 will vary in length and have multiple types present (strings and numbers).

MY CODE

function diff(arr1, arr2) {
  var diffArr = [];

  if (arr1.length >= arr2.length) {
    for (var i = 0; i < arr1.length; i++){
      if (arr2.indexOf(arr1[i]) < 0) {
          diffArr.push(arr1[i]);
          }
    }
  } else {
    for (var j = 0; j < arr2.length; j++){
      if (arr1.indexOf(arr2[j]) < 0) {
        diffArr.push(arr2[j]);
      }
    }
  }
  return diffArr;
}

ISSUES

diff([1, 2, 'cat', 'fish'], [1, 2, 3,'dog']); //returns only ['cat', 'fish']

I am pretty sure that my code is only returning the duplicates in one of the arrays via diffArr.push (even if there are unique values in both arrays). However, I am unsure how to overcome this.

My references

Removes Duplicates from Javascript Arrays

Removed Duplicates from an Array Quickly

Javascript Array Difference

1

2 Answers 2

2

Your code currently only crawls through one array (let's call it A) and pushes in all the A values that don't exist in B. You never go the other way and push in the B values that don't exist in A. There's also no need to have different behavior based on which array is longer. Here is the final answer in a simple way:

function diff(arr1, arr2) {
  var diffArr = [];
  for (var i = 0; i < arr1.length; i++) {
    if (arr2.indexOf(arr1[i]) < 0) diffArr.push(arr1[i]);
  }
  for (var j = 0; j < arr2.length; j++) {
    if (arr1.indexOf(arr2[j]) < 0) diffArr.push(arr2[j]);
  }
  return diffArr;
}

And in a slightly more functional way:

function diff(arr1, arr2) {
  var elsIn1Not2 = arr1.filter(function(el){ return arr2.indexOf(el) < 0; });
  var elsIn2Not1 = arr2.filter(function(el){ return arr1.indexOf(el) < 0; });
  return elsIn1Not2.concat(elsIn2Not1);
}

Both functions return [ 'cat', 'fish', 3, 'dog' ] for your example.

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you for this - I've been struggling with developing a more functional way of programming. I've been having trouble specifically with .filter() (the MDN example isn't great). Upvoted and labeled as the correct answer!
Thanks. :-) If you really want to make it concise, you could change return arr2.indexOf(el) < 0; to return !~arr2.indexOf(el. ;-) That might just be the only mainstream use of the ~ operator (bitwise NOT)…
0
function diff(arr1, arr2) {
  var diffArr = {};

  if (arr1.length >= arr2.length) {
    for (var i = 0; i < arr1.length; i++){
      if (arr2.indexOf(arr1[i]) < 0) {
          diffArr[arr1[i]] = 1;
          }
    }
  } else {
    for (var j = 0; j < arr2.length; j++){
      if (arr1.indexOf(arr2[j]) < 0) {
        diffArr[arr2[j]] = 2;
      }
    }
  }
  return diffArr.keys();
}

1 Comment

This doesn't solve the author's question, which seems to be "how can I get an array of all the elements not shared by both arrays." If you keep that if-else, then you'll only ever get a one-way diff.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.