与Javascript对象数组的SQL完全连接的等价物

时间:2016-10-18 00:28:13

标签: javascript arrays json

我知道有很多"在JS"中合并两个对象数组。问题,我已经阅读了大部分内容。 与我试图做的最相似的是:

How can I merge properties of two JavaScript objects dynamically?

Native javascript - merge two arrays of objects

How to merge two array of objects SQL style JOIN on JSON data

我的问题不同,因为我试图进行完整的SQL连接,其中数组的大小不同,并且会有新列。

例如:

JSON1 = [{Color:"Blue", ID:"15", Size:"Large",Shape:"Square"},
         {Color:"Red", ID:"9", Size:"Medium",Shape:"Circle"},
         {Color:"Red", ID:"2", Size:"Large",Shape:"Triangle"},
         {Color:"Yellow", ID:"3", Size:"Small",Shape:"Square"}];

JSON2 = [{Color:"Blue", Name:"Henry", Inches:"51"},
         {Color:"Red", Name:"Jane", Inches:"7"},
         {Color:"Pink", Name:"Jack", Inches:"14"}];

期望的输出:

OUTPUT =[{Color:"Blue", ID:"15", Size:"Large",Shape:"Square",Name:"Henry", Inches:"51"},
         {Color:"Red", ID:"9", Size:"Medium",Shape:"Circle",Name:"Jane", Inches:"7"},
         {Color:"Red", ID:"2", Size:"Large",Shape:"Triangle",Name:"Jane", Inches:"7"},
         {Color:"Yellow", ID:"3", Size:"Small",Shape:"Square",Name:null, Inches:null},
         {Color:"Pink", ID:null, Size:null,Shape:null,Name:"Jack", Inches:"14"}];

因此,类似于完整的SQL连接,我希望输出JSON包含所有列,匹配时匹配,但如果第二个JSON中的键:值对不匹配,则为新行第一个中任何一个对象中的那些。

到目前为止我的内容如下。它通常有效,但有几个问题。我正在合并一个特定的预定义值,并且函数可以找出匹配值的位置。此外,如果我向JSON2添加多个新属性列,我的函数将失败(即,如果JSON2具有Color和Inches,但不是Color,Inches和Name,则它可以工作。)因为我只是将一个属性散列到另一个属性

var hash={};
for(var e in JSON2){
    hash[JSON2[e]["Color"]]= JSON2[e]["Inches"];
}
var trackHash = hash;
for(var k in JSON1){
    JSON1[k]["Inches"] = hash[JSON1[k]["Color"]];
    if(hash[JSON1[k]["Color"]]===undefined){
        delete trackHash[JSON1[k]["Color"]];
    }
}
for(var obj in JSON2){
    if(trackHash[JSON2[obj]["Color"]]!==undefined){
        JSON1.push(JSON2[obj]);
    }
}

2 个答案:

答案 0 :(得分:3)

我认为这可能是你的事后,...

它可以被优化等,但希望这是一个开始。

哦,为了简单起见,我也使用了Object.assign,因此请注意旧版浏览器,您可能需要使用polyfill,或者使用像lodash这样的东西。

var JSON1 = [{Color:"Blue", ID:"15", Size:"Large",Shape:"Square"},
         {Color:"Red", ID:"9", Size:"Medium",Shape:"Circle"},
         {Color:"Red", ID:"2", Size:"Large",Shape:"Triangle"},
         {Color:"Yellow", ID:"3", Size:"Small",Shape:"Square"}];

var JSON2 = [{Color:"Blue", Name:"Henry", Inches:"51"},
         {Color:"Red", Name:"Jane", Inches:"7"},
         {Color:"Pink", Name:"Jack", Inches:"14"}];

function fullJoin(a, b) {
  var r = [];
  a.forEach(function (a) {
    var found = false;
    b.forEach(function (b) {
      if (a.Color === b.Color) {
        var j = Object.assign(a, b);
        r.push(j);
        found = true;
      }
    })
    if (!found) r.push(a);
  });
  b.forEach(function (b) {
    var found = false;
    a.forEach(function (a) {
       if (a.Color === b.Color) found = true;
    });
    if (!found) r.push(b);
  });
  return r;
}

var a = fullJoin(JSON1, JSON2);
a.forEach(function (a) { console.log(JSON.stringify(a)); });

答案 1 :(得分:0)

所以这就是我对数组做的事情:

  1. 使用Array.prototype.map通过复制JSON1

    <中相应类似键的键/值来从JSON2创建新数组/ LI>
  2. 还跟踪了JSON2中不在JSON1的密钥,并将其添加到其后的结果中。

  3. &#13;
    &#13;
    var JSON1 = [{Color:"Blue", ID:"15", Size:"Large",Shape:"Square"},
             {Color:"Red", ID:"9", Size:"Medium",Shape:"Circle"},
             {Color:"Red", ID:"2", Size:"Large",Shape:"Triangle"},
             {Color:"Yellow", ID:"3", Size:"Small",Shape:"Square"}];
    
    var JSON2 = [{Color:"Blue", Name:"Henry", Inches:"51"},
             {Color:"Red", Name:"Jane", Inches:"7"},
             {Color:"Pink", Name:"Jack", Inches:"14"}];
    
    
    var excluded = {};
    
    // Join JSON2 to JSON1
    // also track elements in JSON2 not in JSON1
    var result = JSON1.map(function(a) {
          JSON2.forEach(function(element, index, array) {
            if (a.Color === element.Color) {
              Object.keys(element).forEach(function(key) {
                a[key] = element[key];
              });
            } else {
                this.visited = this.visited + 1 || 0; 
                if(this.visited == array.length)  {
                  this.found = this.found || [];
                  this.found.push(element);
                }
            }
          }, this);
          this.visited = 0;
            return a;
          }, excluded);
    
    // add elements in JSON2 not in JSON1
    if(excluded.found) {
       excluded.found.forEach(function(element) {
           result.push(element);
       });
    }
    
    console.log(result);
    &#13;
    .as-console-wrapper{top:0;max-height:100%!important;}
    &#13;
    &#13;
    &#13;

    如果这对您有用,请告诉我您的反馈。谢谢!