簡體   English   中英

如何使用JavaScript模仿SQL連接

[英]How to mimic SQL joinings with JavaScript

如何將兩個對象(分數和人)合並為一個對象(已合並)。 我對此感到很掙扎,因為我不熟悉JavaScript,並且正在使用Meteor + Mongo組合。

var scores = [
{person_id: "1", score_math: 9, score_biology: 9, score_chemistry: 9},
{person_id: "2", score_math: 9, score_biology: 8, score_chemistry: 9}
];

var persons = [
{person_id: "1", person_name: "Bob", home_country: "Wakerly", age: 12},
{person_id: "2", person_name: "Arnie", home_country: "Templeton", age: 15},
{person_id: "3", person_name: "Steve", home_country: "Elberon", age: 10}
];


var joined = [
{person_id: "1", person_name: "Bob", home_country: "Wakerly", score_math: 9, score_biology: 9, score_chemistry: 9},
{person_id: "2", person_name: "Arnie", home_country: "Templeton", score_math: 9, score_biology: 8, score_chemistry: 9},
{person_id: "3", person_name: "Steve", home_country: "Elberon", score_math: 0, score_biology: 0, score_chemistry: 0}];

這是一個在香草JS中包含臨時對象和一些數組方法的建議。

 var scores = [{ person_id: "1", score_math: 9, score_biology: 9, score_chemistry: 9 }, { person_id: "2", score_math: 9, score_biology: 8, score_chemistry: 9 }], persons = [{ person_id: "1", person_name: "Bob", home_country: "Wakerly", age: 12 }, { person_id: "2", person_name: "Arnie", home_country: "Templeton", age: 15 }, { person_id: "3", person_name: "Steve", home_country: "Elberon", age: 10 }], joined = persons.map(function (a) { function setProp(o) { Object.keys(o).forEach(function (k) { object[k] = o[k]; }); } var object = {}; setProp(a); setProp(this[a.person_id] || { score_math: 0, score_biology: 0, score_chemistry: 0 }); return object; }, scores.reduce(function (r, a) { r[a.person_id] = a; return r; }, Object.create(null))); document.write('<pre>' + JSON.stringify(joined, 0, 4) + '</pre>'); 

var result = [];
_.forEach(scores,function(score){
    var person = _.find(persons,{person_id:score.person_id});
    result.push(_.extend({}, score, person));
}); 

這是簡化版本。 我不處理找不到的價值,依此類推。 forEach將循環所有分數。 然后我find第一個匹配的人假設它是唯一的。 然后,我使用extend將它們合並到一個新對象中。

小心這種事情,如果您有大量的數據集,則這類任務必須由后台處理。 如果確實需要執行大量聯接並可以更改DBMS,則可以選擇RDBMS(如果適合)。

嘗試:

 var scores = [ {person_id: "1", score_math: 9, score_biology: 9, score_chemistry: 9}, {person_id: "2", score_math: 9, score_biology: 8, score_chemistry: 9} ]; var persons = [ {person_id: "1", person_name: "Bob", home_country: "Wakerly", age: 12}, {person_id: "2", person_name: "Arnie", home_country: "Templeton", age: 15}, {person_id: "3", person_name: "Steve", home_country: "Elberon", age: 10} ]; var joined = []; for (var i=0; i<persons.length; i++) { var new_object = {}; var found = false; for (var j=0; j<scores.length; j++) { if (scores[j].person_id == persons[i].person_id) { found = true; // copy all the values from score for (var key in scores[j]) { new_object[key] = scores[j][key]; } break; } } if (!found) { for (var key in scores[0]) { new_object[key] = 0; } } for (var key in persons[i]) { new_object[key] = persons[i][key]; } joined.push(new_object); } document.body.innerHTML = '<pre>' + JSON.stringify(joined, true, 2) + '</pre>'; 

建議您創建一個同時包含人員和得分詳細信息的新對象,而不是創建一個平面合並對象。

您可以利用.map.filter函數進行管理。

var scores = [
{person_id: "1", score_math: 9, score_biology: 9, score_chemistry: 9},
{person_id: "2", score_math: 9, score_biology: 8, score_chemistry: 9}
];

var persons = [
{person_id: "1", person_name: "Bob", home_country: "Wakerly", age: 12},
{person_id: "2", person_name: "Arnie", home_country: "Templeton", age: 15},
{person_id: "3", person_name: "Steve", home_country: "Elberon", age: 10}
];

//Function used in the .filter method. 'this' object is actually the person_id
function getScoreByPersonId(score){
  return score.person_id == this;
}

//Basic students implementations. You can enrich the structure of the 'item' object depending on your requirements.
var students = persons.map(function(p){
  var item = {};
  item['person'] = p;
  item['score'] = scores.filter(getScoreByPersonId, p.person_id)[0] || {};
  return item;

});

您可以通過基本的數組和對象操作來做到這一點。 下面的代碼進行了優化。

 var scores = [ {person_id: "1", score_math: 9, score_biology: 9, score_chemistry: 9}, {person_id: "2", score_math: 9, score_biology: 8, score_chemistry: 9} ]; var persons = [ {person_id: "1", person_name: "Bob", home_country: "Wakerly", age: 12}, {person_id: "2", person_name: "Arnie", home_country: "Templeton", age: 15}, {person_id: "3", person_name: "Steve", home_country: "Elberon", age: 10} ]; innerjoin=function(data1,data2,column){ var joined=[]; var d1len=data1.length; var d2len=data2.length; // Create dictionary from first array var dict={}; for(var i=0; i<d1len; i++){ var item=data1[i]; var key=item[column]; var arr=dict[key]; if(!arr){ arr=dict[key]=[]; } arr.push(item); } // Join two arrays for(var i=0; i<d2len; i++){ var item=data2[i]; var key=item[column]; var arr=dict[key]; if(!arr) continue; for(var j=0,lenj=arr.length; j<lenj; j++) { joined.push(merge(item,arr[j])); } } return joined; } merge=function(obj1,obj2){ var res={}; for(var key in obj1){ if(obj1.hasOwnProperty(key)) res[key]=obj1[key]; } for(var key in obj2){ if(obj2.hasOwnProperty(key)) res[key]=obj2[key]; } return res; } console.log(innerjoin(persons,scores,"person_id")); 

您可以使用StrelkiJS輕松進行這種連接:

var persons = new StrelkiJS.IndexedArray();
persons.loadArray([
  {id: "1", person_name: "Bob", home_country: "Wakerly", age: 12},
  {id: "2", person_name: "Arnie", home_country: "Templeton", age: 15},
  {id: "3", person_name: "Steve", home_country: "Elberon", age: 10}
]);

var scores = new StrelkiJS.IndexedArray();
scores.loadArray([
  {id: "1", score_math: 9, score_biology: 9, score_chemistry: 9},
  {id: "2", score_math: 9, score_biology: 8, score_chemistry: 9}
]);

var res = persons.query([{
    from_col:"id",
    to_table: scores,
    to_col: "id",
    type: "outer"
}]);

結果將是:

[
  [
    {"id":"1","person_name":"Bob","home_country":"Wakerly","age":12},
    {"id":"1","score_math":9,"score_biology":9,"score_chemistry":9}
  ],
  [
    {"id":"2","person_name":"Arnie","home_country":"Templeton","age":15},
    {"id":"2","score_math":9,"score_biology":8,"score_chemistry":9}
  ],
  [
    {"id":"3","person_name":"Steve","home_country":"Elberon","age":10},
    null
  ]
]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM