在 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
Joins in Javascript
提问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),[]);