Solution to Diff Two Arrays Not Working?

Hello all,

It seems like I was able to make code that works, but for some reason it doesn’t pass three of the tests, despite the information logged seemingly being fine.

The three cases are:

[1, 2, 3, 5], [1, 2, 3, 4, 5] should return [4] .

[1, "calf", 3, "piglet"], [1, "calf", 3, 4] should return ["piglet", 4] .

[1, "calf", 3, "piglet"], [7, "filly"] should return [1, "calf", 3, "piglet", 7, "filly"] .

Thank you,

-Patrick


function diffArray(arr1, arr2) {
  let objects = {}

  for (let i = 0; i < arr1.length; i++){
    objects[arr1[i]] = (objects[arr1[i]] || 0) + 1
    console.log(objects)
  }

  for (let i = 0; i < arr2.length; i++){
    objects[arr2[i]] = (objects[arr2[i]] || 0) + 1
    console.log(objects)
  }

  var newArr = [];
  
  for (let property in objects){
    if (objects[property] == 1){
      console.log("Found one!")
      newArr.push(property)
    }
  }
  console.log(newArr)
  
  return newArr;
}

diffArray([1, "calf", 3, "piglet"], [7, "filly"]);

Your browser information:

User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36.

Welcome to the issue of using objects

You don’t have any guarantee that the properties of an object are in the order you created them.

You can see the issue if you look at the execution of your code with a tool like Python Tutor

Thank you for sharing that! That tool is actually very illuminating; I was wondering how some of that works. The problem, though, states, “You can return the array with its elements in any order.” If it’s just an ordering issue, shouldn’t my code still work?

Yeah, I think the object issue is a big part of the problem. Don’t confuse arrays with objects. Technically, array are objects, but they have some different behavioral characteristics. And what you are creating here (by trying to index an object like an array is what JS calls an “array-like object”.

So, when you loop through your final object, those properties are strings. This is a problem because in the original array, they may have been strings, but also may have been other things.

So, for example in the

diffArray([1, 2, 3, 5], [1, 2, 3, 4, 5])

test, the return is

["4"]

notice that it is a string and not a number. This is an important difference. Notice that your code fails for any answer that requires you to return a number.

I think you should rethink your plan of attack here. You definitely don’t need an object. But I think you can think of a better solution than this approach. I can think of two approaches off the top of my head.

If you want some hints:

One would be to combine both arrays, sort the big array, create a solution array of just the elements that don’t have duplicates. Or loop through the big array and remove duplicates and return the result.

Another option would be to loop through one array and push on anything that isn’t in the first array onto and answer array and then do the reverse on the other.

There are other approaches, but that will get you thinking.

No, the order has nothing to do with it. If I look at the chai test for that example, I see:

        {
          "text": "<code>[1, 2, 3, 5], [1, 2, 3, 4, 5]</code> should return <code>[4]</code>.",
          "testString": "assert.sameMembers(diffArray([1, 2, 3, 5], [1, 2, 3, 4, 5]), [4], '<code>[1, 2, 3, 5], [1, 2, 3, 4, 5]</code> should return <code>[4]</code>.');"
        },

The chai function assert.sameMembers* doesn’t care about order. From the chai docs:


.sameMembers(set1, set2, [message])

Asserts that set1 and set2 have the same members in any order. Uses a strict equality check (===).

assert.sameMembers([ 1, 2, 3 ], [ 2, 1, 3 ], 'same members');

Order is not the issue. But it is a strict equality so type is important.

All the methods suggested on this thread are not efficient it would require you to loop through the same array multiple times for each element of the 2nd array. O(n^2)

The approach he has is fine. O(n). He just needs to address whenever a number is a string.

hint: isNaN()

Also this suggestion doesn’t work:

“… combine both arrays, sort the big array, create a solution array of just the elements that don’t have duplicates”.

fails to

var a1 = [1, 4, 1];
var a2 = [2, 4, 2];

[1, 1, 2, 2, 4, 4] with your suggestion would return an empty array.

Also., read the note in the challenge instructions:

**Note**
You can return the array with its elements in any order.

Hello all,

Since my last reply, I actually did implement a check that sees if there is a number represented as a string and converts it to being represented as an actual number (although I did it in a less elegant way than isNaN(), gotta remember that one). However, even though I got it to pass the FCC test, I believe this would still not be a perfect solution, since if it was passed in, say, ([“1”,2,“3”,4,“5”],[2,“3”]), it would convert all of the arguments to numbers, without regard to whether it’s a number or a string.

Since I passed the test, I’m moving on for now, but I’ve bookmarked it to return to later; if anyone still wants to provide further insight, though, it would be greatly appreciated. I’ve already learned a lot from this thread.

1 Like