web-dev-qa-db-ja.com

オブジェクトのリストから個別のリストを取得する方法は?

List<MyClass> someListがあります。

class MyClass
{
    public int Prop1...
    public int Prop2...
    public int Prop3...
}

List<MyClass> distinctListから新しい別個のList<MyClass> someListを取得する方法を知りたいのですが、それをProp2と比較するだけです。

42
Willem

残念ながら、フレームワークにはこれに対する実際の簡単な組み込みサポートはありませんが、 DistinctBy の実装を使用できます MoreLINQ

あなたが使用します:

var distinctList = someList.DistinctBy(x => x.Prop2).ToList();

DistinctBy実装のみを使用できます。Microsoft実装を使用する場合は、 Reactive Extensions のSystem.Interactive Assemblyに類似したものがあると思います。)

52
Jon Skeet

DistinctByを使用してGroupByの効果をエミュレートし、各グループの最初のエントリのみを使用できます。ただし、他の実装よりも少し遅くなる場合があります。

someList.GroupBy(elem=>elem.Prop2).Select(group=>group.First());
90
CodesInChaos

.Distinct(..);拡張メソッドを使用する必要があります。以下に簡単なサンプルを示します。

public class Comparer : IEqualityComparer<Point>
    {
        public bool Equals(Point x, Point y)
        {
            return x.X == y.X;
        }

        public int GetHashCode(Point obj)
        {
            return (int)obj.X;
        }
    }

GetHashCodeを忘れないでください

使用法:

List<Point> p = new List<Point>();
// add items
p.Distinct(new Comparer());
19
Ilya Smagin

Equals(object obj)およびGetHashCode()メソッドをオーバーライドします。

class MyClass
{
    public int Prop1 { get; set; }
    public int Prop2 { get; set; }
    public int Prop3 { get; set; }

    public override bool Equals(object obj)
    {
        return ((MyClass)obj).Prop2 == Prop2;
    }
    public override int GetHashCode()
    {
        return Prop2.GetHashCode();
    }
}

そして、単に呼び出します:

List<MyClass> distinctList = someList.Distinct().ToList();

Prop2-Propertyのみをチェックする IEqualityComparer インターフェイスを実装するクラスを作成します。その後、このクラスのインスタンスをDistinct拡張メソッドに渡すことができます。

2
Christian

7年後。後で

私はそれがしばらく前であることを知っていますが、最も簡単な答えが必要でしたが、現時点では(.NET 4.5.1を使用して)次のことが最も簡単な答えであることがわかりました。

IEnumerable<long> allIds = waitingFiles.Values.Select(wf => wf.groupId).Distinct();

私の状況では、次のようなConcurrentDictionaryがあります:ConcurrentDictionary<long, FileModel>

ConcurrentDictionary Valuesプロパティは基本的に私のList<FileModel>

* FileModelには、必ずしも一意ではないgroupIdがあります(ただし、FileModelオブジェクトを辞書に追加するために使用するキー(長い)は、FileModelに一意です)。

*例ではわかりやすくするために名前を付けています。

ポイントは、ConcurrentDictionaryに多数のFileModel(100を想定)があり、それらの100のFileModel内に5つの異なるgroupIdがあることです。

この時点で、個別のgroupIdのリストが必要です。

したがって、FileModelのリストがあれば、コードは次のようになります。

IEnumerable <long> allIds = allFileModel.Select(fm => fm.groupId).Distinct();
1
raddevus

サンプルブローのように、Microsoft Ajax Ultilityライブラリの組み込み関数DistinctByを使用するだけです。

最初のライブラリを含む

using Microsoft.Ajax.Utilities;

それから

var distinctList = yourList.DistinctBy(x => x.Prop2).ToList();
0
Anh Hoang