自定义在 lambda 中相交
本文关键字:lambda 自定义 | 更新日期: 2023-09-27 18:36:47
我想知道是否可以使用 lambda 表达式解决这个问题:
List<Foo> listOne = service.GetListOne();
List<Foo> listTwo = service.GetListTwo();
List<Foo> result = new List<Foo>();
foreach(var one in listOne)
{
foreach(var two in listTwo)
{
if((one.Id == two.Id) && one.someKey != two.someKey)
result.Add(one);
}
}
当然可以!您可以使用 Linq 的 Intersect
扩展方法的重载,该方法需要IEqualityComparer<T>
,如下所示:
public class FooComparer : IEqualityComparer<Foo>
{
public bool Equals(Foo x, Foo y)
{
return x.Id == y.Id && x.someKey != y.someKey;
}
public int GetHashCode(Foo x)
{
return x.Id.GetHashCode();
}
}
...
var comparer = new FooComparer();
List<Foo> listOne = service.GetListOne();
List<Foo> listTwo = service.GetListTwo();
List<Foo> result = listOne.Intersect(listTwo, comparer).ToList();
listOne.SelectMany(x=>listTwo.Where(y=>x.Id==y.Id && x.someKey != y.someKey));
你可以试试:
var result = listOne.Join(listTwo,
(one) => one,
(two) => two,
(one, two) => one,
new MyFooComparer());
MyFooComparer
可能如下所示:
class MyFooComparer : IEqualityComparer<Foo>
{
public bool Equals(Foo x, Foo y)
{
return x.Id == y.Id && x.someKey != y.someKey;
}
public int GetHashCode(Foo obj)
{
return obj.Id.GetHashCode();
}
}
[更新]
我对Intersect
与的表现感到好奇。 Join
所以我在我的解决方案和 @p.s.w.g. 的解决方案之间做了一个小的性能比较(listOne
和 listTwo
各有 10 个项目):
var comparer = new MyFooComparer();
var sw = new Stopwatch();
sw.Start();
for (int i = 0; i < 100000; i++)
{
var result1 = listOne.Intersect(listTwo, comparer).ToList();
}
Console.WriteLine("Intersect: {0}",sw.Elapsed);
sw.Restart();
for (int i = 0; i < 100000; i++)
{
var result = listOne.Join(listTwo,
(one) => one,
(two) => two,
(one, two) => one,
comparer);
}
Console.WriteLine("Join: {0}", sw.Elapsed);
输出:
Intersect: 00:00:00.1441810
Join: 00:00:00.0037063
var result = from one in listOne
join two in listTwo on one.Id equals two.Id
where one.SomeKey != two.SomeKey
select one;
更新:似乎有些人觉得这没有回答这个问题,因为它应该没有使用 lambda。当然是,它只是使用友好的查询语法。
这是完全相同的代码,只是可读性较差:
var result =
listOne.Join(listTwo, one => one.Id, two => two.Id, (one, two) => new { one, two })
.Where(p => p.one.someKey != p.two.someKey)
.Select(p => p.one);