1

我有一个问题,我相信这里有人比我想的更容易解决。我有一个有名字和号码的列表。名称是必需的,可以重复,数字只能是一个,但不是必需的。

|name|number|
|A   |2     |
|A   |      |
|B   |      |
|C   |      |
|C   |      |
|D   |4     |
-------------

此时我正在对名称部分执行 list.Distinct() ,但它不关心数字部分。

newlist = oldlist.Distinct().ToList();

如果一个重复的名字有一个数字,我想保留一个有数字的名字,这不会发生。不会发生两个相同名称和两个不同数字的情况。有任何想法吗?

还有一件事:此时我不关心排序,因为 distinct 会处理好这一点。

我正在添加所有代码以更好地了解 StackOverflow 团队:

    class _ClientComparer : IEqualityComparer<_Client>
{
    #region IEqualityComparer<_Client> Members

    public bool Equals(_Client x, _Client y)
    {
        if ((x.ClientNumber != 0) && (y.ClientNumber != 0))//Both clients with numbers
            if (x.ClientNumber == y.ClientNumber)//both clients number the same then same clients.
                return true;
            else //if not the same they are different
                return false;
        else if (x.ClientName == y.ClientName)
            return true;
        else
            return false;
    }

    public int GetHashCode(_Client obj)
    {
        if (obj.ClientNumber != 0)
            return obj.ClientNumber.GetHashCode();
        else
            return obj.ClientName.GetHashCode();
    }

在 IEqualityComparer 实现之上和 Distinct Call 之下。

        public List<_Client> CollectAllClients()
    {
        List<_Client> ClientList = new List<_Client>();
        while (this.Read())
        {
            if (GetClientNumber() != 0)
                ClientList.Add(CreateClientInstance());
            else
                ClientList.AddRange(CreateClientsInstance());
        }
        ClientList = ClientList.Distinct<_Client>(new _ClientComparer()).ToList<_Client>() ;
        return ClientList;
    }
4

3 回答 3

1

您可以使用分组

        List<MyObject> tests = new List<MyObject>() 
        { 
            new MyObject {Name = "A", Number = 2 },
            new MyObject {Name = "A", Number = null },
            new MyObject {Name = "B", Number = null},
            new MyObject {Name = "C", Number = null},
            new MyObject {Name = "C", Number = null},
            new MyObject {Name = "D", Number = 4}
        };

        var qry = from t in tests
                  group t by t.Name into g
                  select g.Max();

        qry.ToList();

存在MyObject

public class MyObject : IComparable<MyObject>
{
    public string Name { get; set; }
    public int? Number { get; set; }

    public int CompareTo(MyObject other)
    {
        return Comparer<int?>.Default.Compare(this.Number, other.Number);
    }
}

如果您有一个具有不同数字的重复元素(如 {A, 1}, {A, 2}),Max则选择 。

于 2009-06-23T16:23:16.830 回答
0

尝试为您的类型实现一个 IEqualityComparer,并将其作为参数传递给 Distinct(我假设您的列表包含一个字符串元组和一个 Nullable int(元组不是.NET 类 - 直到.Net 4.0)

        private class c : IEqualityComparer<Tuple<string,int?>>
        {

            #region IEqualityComparer<Tuple<string,int?>> Members

            public bool Equals(Tuple<string, int?> x, Tuple<string, int?> y)
            {
                if (x.a.Equals(x.a) && x.b.Equals(y.b))
                    return true;
                return false;
            }

            public int GetHashCode(Tuple<string, int?> obj)
            {
                throw new NotImplementedException();
            }

            #endregion
        }

接着

List<Tuple<string,int?>> list;
.....
list.Distinct(new c());
于 2009-06-23T15:57:21.673 回答
0

如果列表由如下所示的对象组成:

class Record : IEquatable<Record>
{
    public string Name { get; set; }
    public int Number { get; set; }

    public bool Equals(Record r)
    {
        if (r == null) return false;
        return this.Name.Equals(r.Name) && this.Number.Equals(r.Number);
    }
}

其中数字 0 表示没有数字。您可以通过首先排序,然后进行区分来获得结果。Distinct 将保留每个遇到的元素的哈希表,并检查后续元素是否存在。所以:

var newList = oldList.OrderByDescending(x => x.Number).Distinct();
于 2009-06-23T15:57:58.587 回答