2016-04-27 4 views
2

Wie kann ich zwei Objekte (Punkte & Personen) in einem einzigen Objekt (verbunden) verbinden. Ich bin nett damit zu kämpfen, da ich Noobie mit JavaScript bin und ich Meteor + Mongo Combo benutze. SQL-Joins mit JavaScript simulieren

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}]; 

Antwort

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

Dies ist eine vereinfachte Version. Ich handle nicht mit Wert nicht gefunden und so weiter. forEach wird bei allen Punkten wiederholt. Dann bin ich find die erste übereinstimmende Person angenommen, dass es einzigartig ist. Dann füge ich sie unter Verwendung extend in ein neues Objekt zusammen.

Seien Sie vorsichtig mit dieser Art von Sache, wenn Sie eine große Menge an Datensätzen haben, müssen diese Art von Aufgabe von der Rückseite behandelt werden. Wenn Sie wirklich viele Joins durchführen müssen und das DBMS ändern können, können Sie sich für ein RDBMS entscheiden, wenn es mehr passt.

1

Versuch:

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>';

0

Sie dies durch grundlegende Array und Objektoperationen tun können. Der folgende Code ist dafür optimiert.

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"));

2

Dies ist ein Vorschlag mit einem temporären Objekt und einigen Array-Methoden in Vanille 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>');

1

Statt ein flaches fusionierte Objekt zu erstellen, empfehle ich Ihnen ein neues Objekt zu erstellen, die sowohl Personen als auch Partituren Details enthalten.

Sie können auf .map und auf .filter Funktionen nutzen, um das zu verwalten.

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; 

}); 
0

können Sie diese Art tun leicht mit StrelkiJS verbindet:

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" 
}]); 

Das Ergebnis wird sein:

[ 
    [ 
    {"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 
    ] 
]