11

我想知道这是否可以使用 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);
    }
}
4

4 回答 4

13

你当然可以!你可以使用Linq 的扩展方法的重载,它需要一个,如下所示:IntersectIEqualityComparer<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();
于 2013-10-25T07:35:32.213 回答
5
listOne.SelectMany(x=>listTwo.Where(y=>x.Id==y.Id && x.someKey != y.someKey));
于 2013-10-25T07:38:06.123 回答
2
var result = from one in listOne
             join two in listTwo on one.Id equals two.Id
             where one.SomeKey != two.SomeKey
             select one;

更新:似乎有些人觉得这没有回答问题,因为它据说没有使用 lambdas。当然是,它只是使用友好的查询语法。

这是完全相同的代码,只是可读性较差:

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);
于 2013-10-25T07:36:58.670 回答
2

你可以试试:

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我对vs.的性能很好奇,Join所以我在我的解决方案和 @pswg 的解决方案之间做了一个小的性能比较(每个listOnelistTwo10 个项目):

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
于 2013-10-25T07:49:37.527 回答