1

ここにいる誰かが、私が考えているよりも簡単に解決したと確信している問題があります。名前と番号のリストがあります。名前は必須で、重複する可能性があり、番号は 1 つのみですが、必須ではありません。

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

現時点では、名前の部分で list.Distinct() を実行していますが、番号の部分は気にしません。

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

重複している名前の 1 つに番号がある場合、番号のある名前を保持したいのですが、これは起こっていません。2 つの同じ名前と 2 つの異なる番号のケースは発生しません。何か案は?

もう 1 つ: 現時点では、個別の処理が行われるため、並べ替えは気にしません。

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 に答える