JavaScript 中对象数组的联合?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13319150/
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
Union of Array of Objects in JavaScript?
提问by Sahat Yalkabov
So after searching the interwebz for a few hours I have not found the solution I am looking for.
所以在interwebz搜索了几个小时后,我还没有找到我正在寻找的解决方案。
I have two arrays that contain game objects with a lot of information inside. (e.g. title, slug, thumbnail, summary, genre, release date...).
我有两个数组,其中包含内部包含大量信息的游戏对象。(例如标题、slug、缩略图、摘要、流派、发布日期...)。
The Array 1is a collection of objects that match user's interests specified during the registration.
所述阵列1是,在注册过程中指定的匹配用户的兴趣对象的集合。
The Array 2is a collection of objects that match purchased games of similar users. (Similar users are those that share common interests)
该阵列2是对象的集合,匹配购买的类似用户的游戏。(相似的用户是那些有共同兴趣的人)
Problem: It is possible, and what is happening in my case, there are two identical games - the game in Array 1 is also in Array 2. In the first array the game is there because it matches user's interests. In the second array the game is there because a similar user has bought that game.
问题:这是可能的,在我的情况下发生了什么,有两个相同的游戏 - 数组 1 中的游戏也在数组 2 中。在第一个数组中,游戏在那里,因为它符合用户的兴趣。在第二个数组中,游戏存在是因为类似的用户已经购买了该游戏。
Question: Underscore.js has a nice little function union() http://underscorejs.org/#unionthat gives you a union of two arrays, but it does not work with an array of objects, only on primitive values. How could I make it work give me a union of array of objects?
问题:Underscore.js 有一个不错的小函数 union() http://underscorejs.org/#union,它为您提供两个数组的并集,但它不适用于对象数组,仅适用于原始值。我怎样才能让它工作给我一个对象数组的联合?
回答by Chris Hayes
You could implement your own pretty easily. In this case, we make the function generic, so that it can take arrays of any data type(s) and union them using the comparator function provided.
你可以很容易地实现你自己的。在这种情况下,我们将函数设为泛型,以便它可以采用任何数据类型的数组,并使用提供的比较器函数将它们联合起来。
// arr1 and arr2 are arrays of any length; equalityFunc is a function which
// can compare two items and return true if they're equal and false otherwise
function arrayUnion(arr1, arr2, equalityFunc) {
var union = arr1.concat(arr2);
for (var i = 0; i < union.length; i++) {
for (var j = i+1; j < union.length; j++) {
if (equalityFunc(union[i], union[j])) {
union.splice(j, 1);
j--;
}
}
}
return union;
}
function areGamesEqual(g1, g2) {
return g1.title === g2.title;
}
// Function call example
arrayUnion(arr1, arr2, areGamesEqual);
Refer to Object comparison in JavaScriptfor various object comparison implementations.
有关各种对象比较实现,请参阅JavaScript中的对象比较。
回答by Arnaud Valensi
You can do it using the underscore way:
您可以使用下划线方式来做到这一点:
// collectionUnion(*arrays, iteratee)
function collectionUnion() {
var args = Array.prototype.slice.call(arguments);
var it = args.pop();
return _.uniq(_.flatten(args, true), it);
}
It just an improvment of the original function _.union(*arrays)
, adding an iteratee to work collection (array of object).
它只是对原始函数的改进,_.union(*arrays)
向工作集合(对象数组)添加了一个迭代对象。
Here how to use it:
这里如何使用它:
var result = collectionUnion(a, b, c, function (item) {
return item.id;
});
The original function which is just working with array, looks like that:
仅使用数组的原始函数如下所示:
_.union = function() {
return _.uniq(flatten(arguments, true, true));
};
And in bonus a full example:
还有一个完整的例子:
// collectionUnion(*arrays, iteratee)
function collectionUnion() {
var args = Array.prototype.slice.call(arguments);
var it = args.pop();
return _.uniq(_.flatten(args, true), it);
}
var a = [{id: 0}, {id: 1}, {id: 2}];
var b = [{id: 2}, {id: 3}];
var c = [{id: 0}, {id: 1}, {id: 2}];
var result = collectionUnion(a, b, c, function (item) {
return item.id;
});
console.log(result); // [ { id: 0 }, { id: 1 }, { id: 2 }, { id: 3 } ]
回答by Vlad Bezden
回答by Murad Hossain
Here is better solution
这是更好的解决方案
function arrayUnion() {
var args = Array.prototype.slice.call(arguments);
var it = args.pop();
return _.uniq(_.flatten(args, true), it);
}
var a = [{id: 0}, {id: 1}, {id: 2}];
var b = [{id: 2}, {id: 3}];
var c = [{id: 0}, {id: 1}, {id: 2}];
var result = arrayUnion(a, b, c, function (item) {
return item.id;
});
console.log(result);
回答by John Salvatier
Using underscore extend, you can do:
使用下划线扩展,您可以执行以下操作:
var objects = [{ bar : 1, nuts : 2} , {foo : 3, nuts : 4}]
_.extend.apply(this,objects)
If the list can be empty, make sure to append an empty object to it.
如果列表可以为空,请确保向其附加一个空对象。