Left join Faild
Closed this issue · 5 comments
import { asEnumerable as linq } from 'linq-es5';
const yx = [
{ id: '1', batchNumber: 'ZKFM1' },
{ id: '2', batchNumber: 'ZKFM' },
{ id: '3', batchNumber: 'ZKFM1' }
];
const zx = [
{ id: '1', value: 'zzz' },
{ id: '2', value: 'xxx' },
];
// LEFT JOIN
const yyy = linq(yx).GroupJoin(zx, a => a.id, b => b.id, (a, temp) => ({ a, temp }))
.SelectMany((t1: any) => linq(t1.temp).DefaultIfEmpty(), (t1: any, t: any) =>
({
id: t1.a.id,
batchNumber: t1.a.batchNumber,
value: t == null ? null : t.value,
}))
.ToArray();
console.log(JSON.stringify(yyy));
the answer as blow:
[
{
"id": "1",
"batchNumber": "ZKFM1",
"value": "zzz"
},
{
"id": "2",
"batchNumber": "ZKFM",
"value": "xxx"
}
]
i hope it will be:
[
{
"id": "1",
"batchNumber": "ZKFM1",
"value": "zzz"
},
{
"id": "2",
"batchNumber": "ZKFM",
"value": "xxx"
},
{
"id": "3",
"batchNumber": "ZKFM1",
"value": null
}
]
import { asEnumerable as linq } from 'linq-es5';
import { asEnumerable as linq } from 'linq-es2015';
both have the same result.
Key should not be composite object
In C# code, the same left join code as below:
var yx = new[]
{
new { id= "1", batchNumber= "ZKFM1" },
new { id= "2", batchNumber= "ZKFM" },
new { id= "3", batchNumber= "ZKFM1" }
};
var zx = new[]
{
new { id= "1", value= "zzz" },
new { id= "2", value= "xxx" },
};
// LEFT JOIN
var yyy = yx.GroupJoin(zx, a => a.id, b => b.id, (a, temp) => new { a, temp })
.SelectMany(t1 => t1.temp.DefaultIfEmpty(), (t1, t) => new
{
id = t1.a.id,
batchNumber = t1.a.batchNumber,
value = t?.value,
})
.ToArray();
foreach (var item in yyy)
{
Console.WriteLine(JsonConvert.SerializeObject(item));
}
the result is:
{"id":"1","batchNumber":"ZKFM1","value":"zzz"}
{"id":"2","batchNumber":"ZKFM","value":"xxx"}
{"id":"3","batchNumber":"ZKFM1","value":null}
what's the useage of linq-es5 or linq-es2015?
Good catch! Thank you!
linq-es5 compatible with old Node. linq-es2015 compatible with latest EcmaScript-2015
Hi' I just run the code OP has posted and i'm still getting 2 columns instead of 3.
To fix it, Instead of using .DefaultIfEmpty()
i just return an [0]
for temp instead (during groupjoin transform).
Also, for anyone interested, I extracted the code into a leftOuterJoin
function
function leftOuterJoin(a, b, sel, transform) {
//a is assumed to already be Enumerable
return a.GroupJoin(b, sel, sel, (it, t) => ({it, t: t || [0]}))
.SelectMany(i => i.t, ({it}, s) => transform(it,s));
}
So the example above becomes:
const result = leftOuterJoin(linq(yx), zx, it => it.id, (a,b) => ({
id: a.id,
batchNumber: a.batchNumber,
value: b.value,
})).ToArray();
@ENikS I assume you wouldn't want to implement leftOuterJoin directly on the Enumerable, since it's not part of LINQ, but perhaps it's worth adding it to documentation?