我正在尝试使用我将从第二个对象中查找的元素扩展主对象。
主要集合如下所示:
collection1 = [
{"user":"user1", "category":"cat1", "item":"item2"},
{"user":"user2", "category":"cat2", "item":"item4"}
];
二级集合如下所示:
collection2 = {
"dateStamp":"2016-12-23",
"details":[
{"category":"cat1", "item":"item1", "attribute":"1"},
{"category":"cat1", "item":"item2", "attribute":"2"},
{"category":"cat2", "item":"item3", "attribute":"1"},
{"category":"cat2", "item":"item2", "attribute":"2"},
{"category":"cat2", "item":"item4", "attribute":"3"}
]
};
我希望最终结果如下:
collection3 = [
{"user":"user1", "category":"cat1", "item":"item2", "dt":"2016-12-23", "attribute":"2"},
{"user":"user2", "category":"cat2", "item":"item4", "dt":"2016-12-23", "attribute":"3"}
];
我正在考虑滚动collection1,并为每条记录查找collection2中的属性值。但是,我还没有上班;目前在查找(查找)方法上失败了。我明显误用了它。 :)
以下代码在注释行上失败:
var collection1 = [
{"user":"user1", "category":"cat1", "item":"item2"},
{"user":"user2", "category":"cat2", "item":"item4"}
];
var collection2 = {
"dateStamp":"2016-12-23",
"details":[
{"category":"cat1", "item":"item1", "attribute":"1"},
{"category":"cat1", "item":"item2", "attribute":"2"},
{"category":"cat2", "item":"item3", "attribute":"1"},
{"category":"cat2", "item":"item2", "attribute":"2"},
{"category":"cat2", "item":"item4", "attribute":"3"}
]
};
var collection3 = [];
collection1.forEach(function(c){
c.dateStamp = collection2.dateStamp;
//c.attribute = collection2.find({"details.category":c.category, "details.item":c.item});
collection3.push(c);
});
console.log(collection3);
我还在想一个类似SQL的"加入"会更有效......但不确定这些数据是否可行。
有人能以最优雅的方式提供有关处理此用例的工作示例和/或指导吗?谢谢!
答案 0 :(得分:1)
圣诞节前夕,希望这会有所帮助:
collection1 = [
{"user":"user1", "category":"cat1", "item":"item2"},
{"user":"user2", "category":"cat2", "item":"item4"}
];
collection2 = {
"dateStamp":"2016-12-23",
"details":[
{"category":"cat1", "item":"item1", "attribute":"1"},
{"category":"cat1", "item":"item2", "attribute":"2"},
{"category":"cat2", "item":"item3", "attribute":"1"},
{"category":"cat2", "item":"item2", "attribute":"2"},
{"category":"cat2", "item":"item4", "attribute":"3"}
]
};
function mergeObjects(obj1,obj2){
var obj3 = {};
for (var attrname in obj1) { obj3[attrname] = obj1[attrname]; }
for (var attrname in obj2) { obj3[attrname] = obj2[attrname]; }
return obj3;
}
function compare(obj,array){
var foundIndex = -1;
var maxCount = 0;
for(var index=0; index < array.length; index++){
var count = 0;
for(var prop in obj){
if(obj[prop] === array[index][prop]){
count++;
}
}
if(count>maxCount){
maxCount = count;
foundIndex = index;
}
}
return array[foundIndex];
}
var collection3 = [];
for(var col1=0; col1 < collection1.length; col1++){
// search in collection2['details'] for each equal collection1 element
var coll2Result = compare(collection1[col1],collection2['details']);
// build a element for collection3
var mergeObj = mergeObjects(collection1[col1], coll2Result);
mergeObj = mergeObjects(mergeObj, {dt: collection2['dateStamp']});
collection3.push(mergeObj);
}
console.log(collection3);
&#13;
答案 1 :(得分:0)
使用Array.prototype.forEach可以计算按类别分组的collection2.details中的元素数。
使用Array.prototype.map之后,可以产生最终结果:
var collection1 = [
{"user":"user1", "category":"cat1", "item":"item2"},
{"user":"user2", "category":"cat2", "item":"item4"}
];
var collection2 = {
"dateStamp":"2016-12-23",
"details":[
{"category":"cat1", "item":"item1", "attribute":"1"},
{"category":"cat1", "item":"item2", "attribute":"2"},
{"category":"cat2", "item":"item3", "attribute":"1"},
{"category":"cat2", "item":"item2", "attribute":"2"},
{"category":"cat2", "item":"item4", "attribute":"3"}
]
};
var hwc2 = {};
collection2.details.forEach(function(ele) {
hwc2[ele.category] = (hwc2[ele.category] === undefined) ? 1 : hwc2[ele.category] + 1;
});
var collection3 = collection1.map(function(val, idx) {
var retVal = val;
retVal['dt'] = collection2.dateStamp;
retVal['attribute'] = hwc2[val.category];
return retVal;
});
console.log(collection3);
答案 2 :(得分:0)
这是一个更简单的问题解决方案。
使用Array#find
方法(请注意,IE不支持,但您可以使用Babel或standalone polyfill),您可以从collection2.details
找到所需的数据。< / p>
var collection1 = [
{"user":"user1", "category":"cat1", "item":"item2"},
{"user":"user2", "category":"cat2", "item":"item4"}
];
var collection2 = {
"dateStamp":"2016-12-23",
"details":[
{"category":"cat1", "item":"item1", "attribute":"1"},
{"category":"cat1", "item":"item2", "attribute":"2"},
{"category":"cat2", "item":"item3", "attribute":"1"},
{"category":"cat2", "item":"item2", "attribute":"2"},
{"category":"cat2", "item":"item4", "attribute":"3"}
]
};
var collection3 = collection1.map((c) => {
c.dateStamp = collection2.dateStamp;
c.attribute = collection2.details.find((detail) => {
return detail.category === c.category && detail.item === c.item;
}).attribute;
return c;
});
console.log(collection3);
对于更保守的浏览器支持方法,您可以使用此版本:
var collection1 = [
{"user":"user1", "category":"cat1", "item":"item2"},
{"user":"user2", "category":"cat2", "item":"item4"}
];
var collection2 = {
"dateStamp":"2016-12-23",
"details":[
{"category":"cat1", "item":"item1", "attribute":"1"},
{"category":"cat1", "item":"item2", "attribute":"2"},
{"category":"cat2", "item":"item3", "attribute":"1"},
{"category":"cat2", "item":"item2", "attribute":"2"},
{"category":"cat2", "item":"item4", "attribute":"3"}
]
};
var collection3 = collection1.map(function(c) {
var detail;
c.dateStamp = collection2.dateStamp;
for (var i = 0; i < collection2.details.length; i++) {
detail = collection2.details[i];
if (detail.category === c.category && detail.item === c.item) {
c.attribute = detail.attribute;
break;
}
}
return c;
});
console.log(collection3);
您还会注意到,在这两个版本中,我都使用Array#forEach
调用替换了Array#map
调用,因为代码的用途更清晰,从collection1
生成新数组。