1

I'm using Angular. I'm trying to compare two arrays of objects I was able to get it working doing it like this:

  var compareUsers = function () {
    //Comparing assigned groups with all to return available users
    var assignedUsersIds = {};
    var usersIds = {};
    availableUsers = []; //declared higher up, populated with user objects on load

    //assignedUsers, declaired higher up, populated by function calling compareUsers
    assignedUsers.forEach(function (el, i) {
      assignedUsersIds[el.id] = assignedUsers[i];
    });

    allUsers.forEach(function (el, i) {
      usersIds[el.id] = allUsers[i];
    });

    for (var i in usersIds) {
        if (!assignedUsersIds.hasOwnProperty(i)) {
            availableUsers.push(usersIds[i]);
        }
    };
    console.log(availableUsers);
    return availableUsers;
  }

I found a better way to do it so I refactored it to this, using lodash:

  var compareUsers = function () {
    availableUsers = _.filter(allUsers, function(user){
      return !_.findWhere(assignedUsers, user);
    });
    console.info(availableUsers);
    return availableUsers;
  }

However, I'm not getting the correct results and not sure what I messed up. The new methods returns availableUsers which are in the assignedUsers list for some groups. The first time it runs, it seems to work but if I keep changing what group i'm looking at the results are all off and don't add up.

I found this method here.

Community
  • 1
  • 1
Batman
  • 5,563
  • 18
  • 79
  • 155

1 Answers1

1

In the first example you are using Array.push, which is always adding up (obviously), no matter how often you call compareUsers.

In the second example you are overwriting availableUsers each time you are calling compareUsers with the result of _.filter

I'd suggest that instead of doing:

availableUsers = _.filter(allUsers, function(user){
    return !_.findWhere(assignedUsers, user);
});

you do:

availableUsers = availableUsers.concat(_.filter(allUsers, function(user){
    return !_.findWhere(assignedUsers, user);
}));

This should work. It will concat the availableUsers array with the result of _.filter.

FlorianTopf
  • 938
  • 6
  • 10
  • Hey so I just tried it. At first it said `couldn't concat undefined` which is likely because I didn't declare it to be an array. So at the very top of the function I set `availableUsers = [];` then what you suggested but now it's just returning an empty array – Batman Dec 26 '15 at 12:12
  • This might be related http://stackoverflow.com/questions/7962953/javascript-how-can-this-function-possibly-return-an-empty-array – Batman Dec 26 '15 at 12:16
  • It will not work if you are setting it as an empty array at the top of the function. In the first example you comment "declared higher up". You should also declare the array outside the function in the second example. I think your lodash filter function is not doing what you want it to do. – FlorianTopf Dec 26 '15 at 12:16
  • It's running but I'm still getting the same issue as before. I'm going to sleep for now, I'll have to get back to this tomorrow. I'll update if i figure it out. – Batman Dec 26 '15 at 12:32
  • Okay, I know what the issue is. Angurlajs is adding a property to the objects called `haskey` but my assigned users array doesn't have this. So when it's checking if the objects are the same, it's seeing this property for one object and not the other so it's returning false. I can't compare the entire object, I have to stick with comparing IDs – Batman Dec 26 '15 at 20:05