Comparing two arrays which contain objects

22,044

Solution 1

I think you should extract ids to an object first and then compare two objects. Eg:

var assignedGroupsIds = {};
var groupsIds = {};
var result = [];

$scope.assignedGroups.forEach(function (el, i) {
  assignedGroupsIds[el.id] = $scope.assignedGroups[i];
});

$scope.groups.forEach(function (el, i) {
  groupsIds[el.id] = $scope.groups[i];
});

for (var i in groupsIds) {
    if (!assignedGroupsIds.hasOwnProperty(i)) {
        result.push(groupsIds[i]);
    }
}

return result;

Here goes simplified fiddle: http://jsfiddle.net/NLQGL/2/ Adjust it to your needs.

I think it's a good solution since you could reuse the groupsIds object (it seems not to change often).

Note: Feel free to use angular.forEach() instead of Array.prototype.forEach

Solution 2

You can use a combination of Angular JS's $filter service and Lo-dash's findWhere method to get unique objects in two arrays, try this :

// When you don't know the lengths of the arrays you want to compare
    var allTheGroupsLength = allTheGroups.length;
    var userGroupsLength = userGroups.length;
    var groupsRemaining = [];

    if(allTheGroupsLength > userGroupsLength){
        getDifference(allTheGroups, userGroups);
    }
    else{
        getDifference(userGroups, allTheGroups);
    }

    function getDifference(obj1, obj2){
        groupsRemaining  = $filter('filter')(obj1, function(obj1Value){
              return !Boolean(_.findWhere(obj2, obj1Value));
        });
    }

OR

//All the groups - user groups = groups remaining

 groupsRemaining  = $filter('filter')(allTheGroups, function(allTheGroupsObj){
                  return !Boolean(_.findWhere(userGroups, allTheGroupsObj));
              });

Using only Angular JS

  groupsRemaining =  $filter('filter')(allTheGroups, function(allTheGroupsObj){
                      return !angular.equals(allTheGroupsObj, $filter('filter')(userGroups, function(userGroupsObj){
                      return angular.equals(allTheGroupsObj,userGroupsObj);})[0]);
                  });
Share:
22,044
Batman
Author by

Batman

Business analyst who dabbles in HTML, JS and CSS when the opportunity rises.

Updated on July 09, 2022

Comments

  • Batman
    Batman almost 2 years

    I have two arrays which only contain objects for groups. One contains all the groups on my site. The other contains all the groups a specific user belongs to.

    I'd like to subtract: All the groups - user groups = groups remaining

    I'm using AngularJS, I'm not sure if that helps here or not (maybe a filter could be used).

    I looked at previous questions and came across some options:

    These are the ones I tried:

    $scope.availableGroups =  $($scope.groups).not($scope.assignedGroups).get();
    $scope.availableGroups = $.grep($scope.groups,function(x) {return $.inArray(x, $scope.assignedGroups) < 0})
    

    This is one of the arrays:

    assignedGroups:

    [{
        id: 115,
        name: 'Test Group 2',
        Description: '',
        owner: 10,
        OwnerIsUser: false,
    }, {
        id: 116,
        name: 'Test Group 3',
        Description: '',
        owner: 71,
        OwnerIsUser: false,
    }, {
        id: 117,
        name: 'Test Group 4',
        Description: '',
        owner: 71,
        OwnerIsUser: false,
    }, {
        id: 118,
        name: 'Test Group 5',
        Description: '',
        owner: 115,
        OwnerIsUser: false,
    }, {
        id: 119,
        name: 'Test Group 6',
        Description: '',
        owner: 8,
        OwnerIsUser: true,
    }];
    
  • Batman
    Batman over 10 years
    I don't understand. I'm trying to get a 3rd array that's the difference between 2 array of objects. This solution is just comparing two arrays.
  • Thomas Junk
    Thomas Junk over 10 years
    I added a Fiddle for that case.
  • Batman
    Batman over 10 years
    You answer is the only one that actually works. I'm just having a hard time understanding it. I'll take a look at the documentation tomorrow, that might help. Thanks.
  • Batman
    Batman over 10 years
    I tried your solution but edited the groups to reflect how my data is modeled. It doesn't work unfortunately. jsfiddle.net/UDaUG/6
  • Batman
    Batman over 10 years
    Hey, I'm still working on this. I think I'm running into a timing issue: I've uploaded my service and added some notes: jsfiddle.net/9dz5A/1
  • Michał Miszczyszyn
    Michał Miszczyszyn over 10 years
    I think your comment is a completely different issue. I have no idea what SPServices is and how possibly could I test or debug this. But I'm pretty sure assignedGroups in your code is undefined. Maybe it's a scoping issue?