Как изменить отличительную функциональность в .NET? - PullRequest
1 голос
/ 23 июня 2009

У меня есть проблема, которую, я уверен, кто-то здесь решил проще, чем то, что я думаю сделать. У меня есть список, который имеет имя и номер. Имя является обязательным и может быть повторным, а номер может быть только одним, но не обязательным.

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

В данный момент я выполняю list.Distinct () для части имени, но не заботится о разделе номера.

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

Если одно имя с дубликатом имеет номер, я хочу оставить имя с номером, чего не происходит. Случай двух одинаковых имен и двух разных чисел не произойдет. Есть идеи?

Еще одна вещь: в данный момент я не забочусь о сортировке, так как об этом позаботятся разные.

Я добавляю весь код для лучшей наглядности команды 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 и ниже Различного вызова.

        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;
    }

Ответы [ 3 ]

1 голос
/ 23 июня 2009

Вы можете использовать группировка :

        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.

0 голосов
/ 23 июня 2009

Если список состоит из объектов, которые выглядят так:

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();
0 голосов
/ 23 июня 2009

попробуйте реализовать IEqualityComparer для вашего типа и передать его в качестве параметра в Distinct (я предполагаю, что ваш список содержит Tuple из строки и Nullable int (Tuple не является классом .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());
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...