javascript 比较两个包含对象的数组
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/21214105/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Comparing two arrays which contain objects
提问by Batman
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
我想减去: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).
我正在使用 AngularJS,我不确定这是否有帮助(也许可以使用过滤器)。
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,
}];
采纳答案by Micha? Miszczyszyn
I think you should extract ids to an object first and then compare two objects. Eg:
我认为您应该先将 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;
Here goes simplified fiddle: http://jsfiddle.net/NLQGL/2/Adjust it to your needs.
这是简化的小提琴:http: //jsfiddle.net/NLQGL/2/根据您的需要调整它。
I think it's a good solution since you could reuse the groupsIds
object (it seems not to change often).
我认为这是一个很好的解决方案,因为您可以重用该groupsIds
对象(似乎不经常更改)。
Note: Feel free to use angular.forEach()
instead of Array.prototype.forEach
注意:随意使用angular.forEach()
而不是Array.prototype.forEach
回答by Ajay Ullal
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 :
您可以结合使用 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));
});
}
OR
或者
//All the groups - user groups = groups remaining
groupsRemaining = $filter('filter')(allTheGroups, function(allTheGroupsObj){
return !Boolean(_.findWhere(userGroups, allTheGroupsObj));
});
Using only Angular JS
仅使用 Angular JS
groupsRemaining = $filter('filter')(allTheGroups, function(allTheGroupsObj){
return !angular.equals(allTheGroupsObj, $filter('filter')(userGroups, function(userGroupsObj){
return angular.equals(allTheGroupsObj,userGroupsObj);})[0]);
});
回答by Prateek
You can try this
你可以试试这个
// .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;
}
Result
结果
[1, 2, [3, 4]].compare([1, 2, [3, 4]]) === true;
[1, 2, 1, 2].compare([1, 2, 1, 2]) === true;
Json Diff
杰森·迪夫
function diff(obj1, obj2)
{
var result = {};
$.each(obj1, function (key, value)
{
if (!obj2.hasOwnProperty(key) || obj2[key] !== obj1[key])
{
result[key] = value;
}
});
return result;
}
回答by Thomas Junk
(maybe a filter could be used).
(也许可以使用过滤器)。
If you want to filter out all unused groups, a filter is the right decision:
如果您想过滤掉所有未使用的组,过滤器是正确的决定:
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;
}));
Here is the Fiddle.
这是小提琴。
For the documentation take a loog at MDN Array.prototype.filter
有关文档,请查看 MDN Array.prototype.filter
For a future solution with find
or findIndex
take a look at thisfine article.
对于未来的解决方案,find
或者findIndex
看看这篇精美的文章。
Edit: For dealing with Objects
you could easily adapt the filter function and use a custom comparator function instead indexOf
. Here another Fiddlefor that case.
编辑:为了处理,Objects
您可以轻松地调整过滤器功能并改用自定义比较器功能indexOf
。这是该案例的另一个小提琴。