2013-07-26 8 views
9

Mam 2 listy obiektów:Łączy w JavaScript

people = 
[{id: 1, name: "Tom", carid: 1}, 
{id: 2, name: "Bob", carid: 1}, 
{id: 3, name: "Sir Benjamin Rogan-Josh IV", carid: 2}]; 

cars= 
[{id: 1, name: "Ford Fiesta", color: "blue"}, 
{id: 2, name: "Ferrari", color: "red"}, 
{id: 3, name: "Rover 25", color: "Sunset Melting Yellow with hints of yellow"}]; 

Czy istnieje funkcja (ewentualnie w kątowa, jQuery, podkreślenia, LoDash lub innej zewnętrznej biblioteki) wykonać LEFT JOIN w jednej linii na nich ? Coś jak:

peoplewithcars = leftjoin(people, cars, "carid", "id"); 

Mogę napisać własną, ale jeśli LoDash ma zoptymalizowaną wersję, chciałbym z niej skorzystać.

Odpowiedz

3

To nie jest trudne do realizacji z wykorzystaniem underscore.js

function leftJoin(left, right, left_id, right_id) { 
    var result = []; 
    _.each(left, function (litem) { 
     var f = _.filter(right, function (ritem) { 
      return ritem[right_id] == litem[left_id]; 
     }); 
     if (f.length == 0) { 
      f = [{}]; 
     } 
     _.each(f, function (i) { 
      var newObj = {}; 
      _.each(litem, function (v, k) { 
       newObj[k + "1"] = v; 
      }); 
      _.each(i, function (v, k) { 
       newObj[k + "2"] = v; 
      }); 
      result.push(newObj); 
     }); 
    }); 
    return result; 
} 

leftJoin(people, cars, "carid", "id"); 
1

Nie, LoDash nie ma dołączyć to prety łatwe do wdrożenia własnego chociaż nie jest to całkiem przyłączyć ale wybiera wszystkich ludzi z dopasowanym samochodu:

var peopleWithCars = _.filter(people, function (person) { 
     return _.exists(cars, function(car) { 
      return car.id === person.id; 
     }); 
    }); 
1

można wykorzystać Alasql JavaScript SQL bibliotekę do łączenia dwóch lub więcej tablic obiektów:

var res = alasql('SELECT people.name AS person_name, cars.name, cars.color \ 
    FROM ? people LEFT JOIN ? cars ON people.carid = cars.id',[people, cars]); 

Wypróbuj ten przykład: at jsFiddle.

0

Oto prosta pętla, którą zrobiłem dla JavaScript (w tym przypadku JQuery), aby "dołączyć" obj1 i obj2 na someID i dodać jedną właściwość z obj2 do obj1.

Jeśli chcesz wykonać bardziej kompletne łączenie, możesz przejść i rozwinąć go, aby zapętlić na obj2.hasOwnProperty() i skopiuj go również.

$.each(obj1,function(i){ 
     $.each(obj2, function(k){ 
      if (obj2[k].someID == obj1[i].someID){ 
       obj1[i].someValue = obj2[k].someValue; 
      } 
     }); 
    }); 
0

tym przykładzie użyto Lodash do lewej łączyć pierwszą dopasowanego obiektu. Nie do końca pytanie, które zadaje, ale podobna odpowiedź była dla mnie pomocna.

var leftTable = [{ 
 
    leftId: 4, 
 
    name: 'Will' 
 
}, { 
 
    leftId: 3, 
 
    name: 'Michael' 
 
}, { 
 
    leftId: 8, 
 
    name: 'Susan' 
 
}, { 
 
    leftId: 2, 
 
    name: 'Bob' 
 
}]; 
 

 
var rightTable = [{ 
 
    rightId: 1, 
 
    color: 'Blue' 
 
}, { 
 
    rightId: 8, 
 
    color: 'Red' 
 
}, { 
 
    rightId: 2, 
 
    color: 'Orange' 
 
}, { 
 
    rightId: 7, 
 
    color: 'Red' 
 
}]; 
 

 
console.clear(); 
 

 
function leftJoinSingle(leftTable, rightTable, leftId, rightId) { 
 
    var joinResults = []; 
 

 
    _.forEach(leftTable, function(left) { 
 
    \t  var findBy = {}; 
 
     findBy[rightId] = left[leftId]; 
 

 
     var right = _.find(rightTable, findBy), 
 
      result = _.merge(left, right); 
 

 
     joinResults.push(result); 
 
    }) 
 

 
    return joinResults; 
 
} 
 

 

 
var joinedArray = leftJoinSingle(leftTable, rightTable, 'leftId', 'rightId'); 
 
console.log(JSON.stringify(joinedArray, null, '\t'));

Wyniki

[ 
 
\t { 
 
\t \t "leftId": 4, 
 
\t \t "name": "Will" 
 
\t }, 
 
\t { 
 
\t \t "leftId": 3, 
 
\t \t "name": "Michael" 
 
\t }, 
 
\t { 
 
\t \t "leftId": 8, 
 
\t \t "name": "Susan", 
 
\t \t "rightId": 8, 
 
\t \t "color": "Red" 
 
\t }, 
 
\t { 
 
\t \t "leftId": 2, 
 
\t \t "name": "Bob", 
 
\t \t "rightId": 2, 
 
\t \t "color": "Orange" 
 
\t } 
 
]

0

Można zrobić takie rzeczy w zwykłym javascript.

people.map(man => 
     cars.some(car => car.id === man.carid) ? 
      cars.filter(car => car.id === man.carid).map(car => ({car, man})) : 
      {man} 
     ).reduce((a,b)=> a.concat(b),[]);