[英]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>';
建議您創建一個同時包含人員和得分詳細信息的新對象,而不是創建一個平面合並對象。
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.