所以在搜索interwebz几个小时后,我找不到我想要的解决方案。
我有两个包含游戏对象的数组,里面有很多信息。 (例如标题,slu ,,缩略图,摘要,流派,发布日期......)。
数组1 是一组符合注册时指定用户兴趣的对象。
阵列2 是与购买类似用户的游戏相匹配的对象的集合。 (类似用户是有共同兴趣的用户)
问题:有可能,在我的情况下发生了什么,有两个相同的游戏 - 阵列1中的游戏也在阵列2中。在第一个阵列中游戏是因为它符合用户的兴趣。在第二个阵列中,游戏就在那里,因为类似的用户已经购买了该游戏。
问题:Underscore.js有一个很好的小函数union()http://underscorejs.org/#union,它为你提供了两个数组的联合,但它不能用于一个对象数组,只能在原始价值观。我怎么能让它工作给我一个对象数组的联合?
答案 0 :(得分:17)
你可以很容易地实现自己的。在这种情况下,我们使函数具有通用性,以便它可以使用任何数据类型的数组,并使用提供的比较器函数将它们联合起来。
// 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);
有关各种对象比较实现,请参阅Object comparison in JavaScript。
答案 1 :(得分:4)
您可以使用下划线方式执行此操作:
// collectionUnion(*arrays, iteratee)
function collectionUnion() {
var args = Array.prototype.slice.call(arguments);
var it = args.pop();
return _.uniq(_.flatten(args, true), it);
}
它只是原始函数_.union(*arrays)
的改进,在工作集合中添加了一个iteratee(对象数组)。
以下是如何使用它:
var result = collectionUnion(a, b, c, function (item) {
return item.id;
});
正在使用数组的原始函数看起来像这样:
_.union = function() {
return _.uniq(flatten(arguments, true, true));
};
奖金中有一个完整的例子:
// 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 } ]
答案 2 :(得分:2)
Set(ES6 / ES2015)会帮助你。
const info1 = {id: 1}
const info2 = {id: 2}
const info3 = {id: 3}
const array1 = [info1, info2]
const array2 = [info1, info3]
const union = [...new Set([...array1, ...array2])]
console.log(union)
&#13;
答案 3 :(得分:1)
jQuery的方法是extend
:
$.extend(true, object1, object2);
答案 4 :(得分:1)
使用下划线扩展,您可以:
var objects = [{ bar : 1, nuts : 2} , {foo : 3, nuts : 4}]
_.extend.apply(this,objects)
如果列表可以为空,请确保向其附加一个空对象。
答案 5 :(得分:1)
这是更好的解决方案
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);
答案 6 :(得分:0)
使用set函数在打字稿中做起来真的很容易。
View
答案 7 :(得分:0)
const a=[
{
id:1,
label:"mnbmnbm1"
},
{
id:2,
label:"mnbmnbm2"
},
{
id:3,
label:"mnbmnbm3"
}
];
const b=[
{
id:1,
label:"mnbmnbm1"
},
{
id:2,
label:"mnbmnbm2"
},
{
id:4,
label:"mnbmnbm5"
}
];
const c=[
{
id:1,
label:"mnbmnbm1"
},
{
id:5,
label:"mnbmnbm5"
},
{
id:6,
label:"mnbmnbm6"
}
];
function arrayUnion(...args){
return arrayUnique(flatten(...args));
}
function flatten(...args){
return args.reduce((acc,cur)=>{
if(Array.isArray(acc) && Array.isArray(cur)){
acc=[...acc,...cur];
return acc;
}
});
}
function arrayUnique(arr){
let map={};
return arr.filter(obj =>{
let objID=obj.id;
if(!map[objID]){
map[objID]=true;
return obj;
}
});
}
console.log("result",arrayUnion(a,b,c));
答案 8 :(得分:0)