【问题标题】:Comparing two arrays which contain objects比较两个包含对象的数组
【发布时间】:2014-02-08 10:45:43
【问题描述】:

我有两个仅包含组对象的数组。一个包含我网站上的所有组。另一个包含特定用户所属的所有组。

我想减去:All the groups - user groups = groups remaining

我正在使用 AngularJS,我不确定这是否有帮助(也许可以使用过滤器)。

我查看了以前的问题并遇到了一些选项:

这些是我尝试过的:

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

这是数组之一:

分配组:

[{
    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,
}];

【问题讨论】:

    标签: javascript jquery arrays angularjs


    【解决方案1】:

    你可以试试这个

    // .compare method to Array's prototype to call it on any array
    Array.prototype.compare = function (array) 
    {
        if (!array)
            return false;
    
        // compare lengths
        if (this.length != array.length)
            return false;
    
        for (var i = 0, l = this.length; i < l; i++)
        {
            if (this[i] instanceof Array && array[i] instanceof Array) 
            {
               if (!this[i].compare(array[i]))
                  return false;
            }
            else if (this[i] != array[i])
            {
                return false;
            }
        }
        return true;
    }
    

    结果

    [1, 2, [3, 4]].compare([1, 2, [3, 4]]) === true;
    [1, 2, 1, 2].compare([1, 2, 1, 2]) === true;
    

    Json 差异

    function diff(obj1, obj2)
     {
        var result = {};
        $.each(obj1, function (key, value)
        {
            if (!obj2.hasOwnProperty(key) || obj2[key] !== obj1[key])
            {
                result[key] = value;
            }
        });
    
        return result;
    }
    

    【讨论】:

    • 我不明白。我正在尝试获得第三个数组,它是 2 个对象数组之间的差异。这个解决方案只是比较两个数组。
    【解决方案2】:

    (也许可以使用过滤器)。

    如果您想过滤掉所有未使用的组,过滤器是正确的决定:

    var groups=["admin","moderator","reader","writer"]
    
    var user={
       name:"the user",
       groups:["reader", "writer"]
    };
    
    console.log(groups.filter(function(group){
        if (user.groups.indexOf(group)==-1) return true;
    }));
    

    这里是Fiddle

    有关文档,请查看 MDN Array.prototype.filter

    有关findfindIndex 的未来解决方案,请查看this 精美文章。

    编辑:为了处理Objects,您可以轻松调整过滤器功能并使用自定义比较器功能代替indexOf。这是另一个Fiddle 用于该案例。

    【讨论】:

    • 我为那个案例添加了一个 Fiddle。
    • 您的回答是唯一有效的。我只是很难理解它。明天我会看一下文档,这可能会有所帮助。谢谢。
    • 我尝试了您的解决方案,但编辑了组以反映我的数据是如何建模的。不幸的是,它不起作用。 jsfiddle.net/UDaUG/6
    【解决方案3】:

    我认为您应该首先将 id 提取到一个对象,然后比较两个对象。例如:

    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;
    

    这里是简化的小提琴:http://jsfiddle.net/NLQGL/2/ 根据您的需要进行调整。

    我认为这是一个很好的解决方案,因为您可以重复使用 groupsIds 对象(它似乎不会经常更改)。

    注意:请随意使用angular.forEach() 而不是Array.prototype.forEach

    【讨论】:

    • 嘿,我还在努力。我想我遇到了时间问题:我已经上传了我的服务并添加了一些注释:jsfiddle.net/9dz5A/1
    • 我认为您的评论是一个完全不同的问题。我不知道 SPServices 是什么以及我怎么可能测试或调试它。但我很确定您代码中的assignedGroups 是未定义的。也许这是一个范围界定问题?
    【解决方案4】:

    您可以结合使用 Angular JS 的 $filter 服务和 Lo-dash 的 findWhere 方法来获取两个数组中的唯一对象,试试这个:

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

    //All the groups - user groups = groups remaining
    
     groupsRemaining  = $filter('filter')(allTheGroups, function(allTheGroupsObj){
                      return !Boolean(_.findWhere(userGroups, allTheGroupsObj));
                  });
    

    仅使用 Angular JS

      groupsRemaining =  $filter('filter')(allTheGroups, function(allTheGroupsObj){
                          return !angular.equals(allTheGroupsObj, $filter('filter')(userGroups, function(userGroupsObj){
                          return angular.equals(allTheGroupsObj,userGroupsObj);})[0]);
                      });
    

    【讨论】:

      猜你喜欢
      • 2019-05-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多