Присоединяется к Javascript

У меня есть 2 списка объектов:

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

Есть ли функция (возможно, в Angular, JQuery, Underscore, LoDash или другая внешняя библиотека), чтобы сделать левое соединение в одной строке? Что-то вроде:

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

Я могу написать свой, но если у LoDash есть оптимизированная версия, я бы хотел использовать это.

Ответ 2

Linq.js http://linqjs.codeplex.com/ будет делать соединения вместе со многими другими вещами

Ответ 3

Нетрудно реализовать, используя 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");

Ответ 4

Нет, у LoDash нет присоединения, это претит легко реализовать свое, хотя это не совсем объединение, но выбирает всех людей с подходящим автомобилем:

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

Ответ 5

Вы можете использовать Alasql JavaScript-библиотека JavaScript для объединения двух или более массивов объектов:

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

Попробуйте этот пример в jsFiddle.

Ответ 6

Вот простой цикл, который я сделал для Javascript (в этом случае JQuery) для "объединения" obj1 и obj2 на someID и добавления одного свойства из obj2 в obj1.

Если вы хотите сделать более полное соединение, вы можете пройти и расширить его до цикла на obj2.hasOwnProperty() и скопировать его также.

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

Ответ 7

В этом примере используется Lodash, чтобы присоединиться к первому совпадающему объекту. Не совсем то, что задает вопрос, но я нашел полезный ответ.

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

Ответ 8

Вы можете делать такие вещи в простом 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),[]);

Ответ 9

В этой реализации используется оператор распространения ES6. Опять же, не библиотечная функция, как просили.

const leftJoin = (objArr1, objArr2, key1, key2) => {
    return objArr1.map(
        anObj1 => ({
            ...objArr2.find(
                anObj2 => anObj1[key1] === anObj2[key2]
            ),
            ...anObj1
        })
    );
};