在 Javascript 中加入

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17880476/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 09:58:16  来源:igfitidea点击:

Joins in Javascript

javascriptjoinunderscore.jslodash

提问by Crashthatch

I have 2 lists of objects:

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

Is there a function (possibly in Angular, JQuery, Underscore, LoDash, or other external library) to do a left join in one line on these? Something like:

是否有一个函数(可能在 Angular、JQuery、Underscore、LoDash 或其他外部库中)在一行中进行左连接?就像是:

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

I can write my own, but if LoDash has an optimised version I'd like to use that.

我可以自己编写,但如果 LoDash 有优化版本,我想使用它。

回答by Geoff

Linq.js http://linqjs.codeplex.com/will do joins along with many other things

Linq.js http://linqjs.codeplex.com/将与许多其他事情一起做连接

回答by zs2020

It is not hard to implement using underscore.js

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

回答by agershun

You can use AlasqlJavaScript SQL library to join two or more arrays of objects:

您可以使用AlasqlJavaScript SQL 库来连接两个或多个对象数组:

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

Try this example at jsFiddle.

在 jsFiddle试试这个例子。

回答by roo2

No, LoDash does not have joinit's prety easy to implement your own though, this isn't quite a join but selects all people with a matching car:

不,LoDash 没有 join实现你自己的很容易,虽然这不是一个 join,而是选择所有拥有匹配汽车的人:

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

回答by Ashley Wilson

This implementation uses the ES6 spread operator. Again, not a library function as asked for.

此实现使用 ES6 扩展运算符。同样,不是所要求的库函数。

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

回答by MaxRocket

Here's a simple loop I did for a Javascript (JQuery in this case) to "join" obj1 and obj2 on someID and add one property from obj2 to obj1.

这是我为 Javascript(在本例中为 JQuery)执行的一个简单循环,用于在 someID 上“连接”obj1 和 obj2,并将一个属性从 obj2 添加到 obj1。

If you want to do a more complete join, you can go through and expand it to loop on obj2.hasOwnProperty() and copy that over as well.

如果你想做一个更完整的连接,你可以通过并扩展它以在 obj2.hasOwnProperty() 上循环并复制它。

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

回答by Will Lovett

This example uses Lodash to left join the first matched object. Not quite what the question asks, but I found a similar answer helpful.

这个例子使用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'));

Results

结果

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

回答by Ерлан Яр-Мухамедов

You can do such stuff in plain javascript.

你可以用普通的 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),[]);