自定义在lambda中相交

时间:2013-10-25 07:33:18

标签: c# asp.net linq lambda set-intersection

我想知道是否可以使用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 个答案:

答案 0 :(得分:12)

当然可以!您可以使用this overload 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();

答案 1 :(得分:4)

listOne.SelectMany(x=>listTwo.Where(y=>x.Id==y.Id && x.someKey != y.someKey));

答案 2 :(得分: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);

答案 3 :(得分: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();
    }
}

<强> [UPDATE]

我对IntersectJoin的效果感到好奇,所以我在我的解决方案和@ pswg(listOnelistTwo之间做了一个小的性能比较每项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