如何使用javascript将主数据集链接到辅助数据集?

时间:2016-12-23 18:19:22

标签: javascript

我正在尝试使用我将从第二个对象中查找的元素扩展主对象。

主要集合如下所示:

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的"加入"会更有效......但不确定这些数据是否可行。

有人能以最优雅的方式提供有关处理此用例的工作示例和/或指导吗?谢谢!

3 个答案:

答案 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;
&#13;
&#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)

这是一个更简单的问题解决方案。

ES6

使用Array#find方法(请注意,IE不支持,但您可以使用Babelstandalone 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);

ES5

对于更保守的浏览器支持方法,您可以使用此版本:

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生成新数组。