I have some problems creating a custom comparer to be used in linq.join. I'm not very expert in linq, so I probably misunderstood join function behavior.
This is my code. I want to perfor a simple join between those two lists:
List<MyObj> operand1Data = new List<MyObj>()
{
new MyObj() { Var = "1var1", Year = 0 },
new MyObj() { Var = "1var2", Year = 2018 },
};
List<MyObj> operand2Data = new List<MyObj>()
{
new MyObj() { Var = "2var1", Year = 2018 },
new MyObj() { Var = "2var2", Year = 2019 },
new MyObj() { Var = "2var3", Year = 2020 },
};
var result= operand1Data.Join(operand2Data, x => x.Year, y => y.Year, (x, y) => x.Var + y.Var, new TestComparer()).ToList();
The problem is that I want 0 to match with every element in the other list, so I came up with this custom comparer:
public class TestComparer : IEqualityComparer<int>
{
public bool Equals(int x, int y)
{
if (x == 0 || y == 0)
{
return true;
}
else
{
return x.Equals(y);
}
}
public int GetHashCode(int obj)
{
return 1;
}
}
This does not work. The result only contains:
"1var12var3"
"1var22var1"
and what I expected was:
"1var12var1"
"1var12var2"
"1var12var3"
"1var22var1"
What am I missing? Can someone help me fixing this? Thanks for your help.
i've tried your code and i guess that LINQ Join have a default filter that gets applied before the custom IEqualityComparer<T>
.
With a log inside the Equals(x,y)
, this is what i got:
"Equality test x:2018 y:2019 = False" "Equality test x:2019 y:2020 = False" "Equality test x:2018 y:2020 = False" "Equality test x:2020 y:0 = True" "Equality test x:2020 y:2018 = False" "Equality test x:2019 y:2018 = False" "Equality test x:2018 y:2018 = True"
You see? Only one "zero" equality check.
So, my suggestion is to use the linq query-syntax with a cross join, then filter elements by where
conditions:
var result = from o1 in operand1Data
from o2 in operand2Data
where o1.Year == 0 || o2.Year == 0 || o1.Year == o2.Year
select o1.Var + o2.Var;
The result is exactly what you're looking for:
"1var12var1" "1var12var2" "1var12var3" "1var22var1"
Hope this helps!
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.