如果重复,LINQ只获得一个

时间:2014-02-13 15:38:51

标签: c# linq

你好我有这个清单

发件人接收器

1 --------------- 2

2 --------------- 1

1 --------------- 3

1 --------------- 2

3 --------------- 1

2 --------------- 1

在这个列表中,我只想得到:

1 - 2和1 - 3

其他是重复的,右边的Id在左边相同,两个id(发送者和接收者)指向同一张桌子,对我来说无论是1-3还是3-1,我都喜欢只得到其中一个。它有可能吗?谢谢!

3 个答案:

答案 0 :(得分:2)

如果您在课堂上(或通过IEqualityComparer<>)实现这样的平等,那么简单的Distinct将为您提供所需的结果:

public class MyClass
{
    public int Sender { get; set; }
    public int Receiver { get; set; }

    public override int GetHashCode()
    {
        return Sender ^ Receiver;
    }
    public override bool Equals(object other)
    {
        if (other == null || this.GetType() != other.GetType())
            return false;
        var o = (MyClass)other;
        return Math.Min(this.Sender, this.Receiver) == Math.Min(o.Sender, o.Receiver) &&
            Math.Max(this.Sender, this.Receiver) == Math.Max(o.Sender, o.Receiver);
    }
}

// use like
var myList = new List<MyClass>
{
    new MyClass { Sender = 1, Receiver = 2 },
    new MyClass { Sender = 2, Receiver = 1 },
    new MyClass { Sender = 1, Receiver = 3 },
    new MyClass { Sender = 1, Receiver = 2 },
    new MyClass { Sender = 3, Receiver = 1 },
    new MyClass { Sender = 2, Receiver = 1 },
};
var distinctOnes = myList.Distinct(); // contains 1,2 and 1,3

答案 1 :(得分:0)

您可以选择较小的发件人/收件人并致电Distinct

list.Select(l => new 
    {
        Sender   = l.Sender < l.Receiver ? l.Sender : l.Receiver,
        Receiver = l.Sender < l.Receiver ? l.Receiver : l.Sender
    })
    .Distinct();

答案 2 :(得分:0)

已经有一些好的答案,但我已经准备好了,所以这里是另一个LINQ解决方案

        var recieverHighArr = from e in list
                      where e.Sender < e.Reciever
                      select new { high = e.Reciever, low = e.Sender };

        var senderHighArr= from e in list
                      where e.Sender >= e.Reciever
                      select new { high = e.Sender, low = e.Reciever };

        var concat = senderHighArr.Concat(recieverHighArr).Distinct();

        foreach (var ob in concat)
        {
            Console.WriteLine(ob.high + " " + ob.low);
        }