web-dev-qa-db-ja.com

Linqを使って個別を選択

私はクラスのクラスリストを持っています

public class LinqTest
{
public int id { get; set; }
public string value { get; set; }
}


List<LinqTest> myList = new List<LinqTest>();
myList.Add(new LinqTest() { id = 1, value = "a" });
myList.Add(new LinqTest() { id = 1, value = "b" });
myList.Add(new LinqTest() { id = 2, value = "c" });

そのリストから個別のIDだけを選択する必要があります。つまり、私の結果リストには、

[{id=1,value="a"},{ id = 2, value = "c" }]

Linqを使ってこれを行うことができますか?

編集

入力、

id      value
1        a
1        b
2        c
3        d
3        e

出力する必要があります、

id      value
1        a
2        c
3        d

すなわち、idの繰り返しがある場合、結果は最初の出現のみを取るべきです。

222
Anoop Joshi
myList.GroupBy(test => test.id)
      .Select(grp => grp.First());

編集:このIEnumerable<>List<>に変換することは多くの人にとって謎であるように思われるので、あなたは単に書くことができます:

var result = myList.GroupBy(test => test.id)
                   .Select(grp => grp.First())
                   .ToList();

しかし、上記のLinqは遅延評価されるので、IEnumerableよりもIListで作業する方が賢明です。列挙型が繰り返されるまで、実際にはすべての作業を行いません。 ToListを呼び出すと、実際には列挙可能なもの全体を調べて、すべての作業を事前に行わなければなりません。 (そして、あなたのenumerableが無限に長いなら、少し時間がかかるかもしれません。)

このアドバイスの裏返しは、そのようなIEnumerableを列挙するたびにそれを評価する作業を新たに行わなければならないということです。そのため、それぞれの場合について、遅延評価されたIEnumerableを使って作業するのが良いのか、それをListSetDictionaryにするのか、それともnotnotにするのが良いのかを判断する必要があります。

453
Paul Ruane

morelinq を使用すると、DistinctByを使用できます。

myList.DistinctBy(x => x.id);

それ以外の場合は、グループを使用できます。

myList.GroupBy(x => x.id)
      .Select(g => g.First());
104
Daniel Hilgarth

この場合はIDを比較するために、EqualsGetHashCodeを有意に上書きする必要があります。

public class LinqTest
{
    public int id { get; set; }
    public string value { get; set; }

    public override bool Equals(object obj)
    {
        LinqTest obj2 = obj as LinqTest;
        if (obj2 == null) return false;
        return id == obj2.id;
    }

    public override int GetHashCode()
    {
        return id;
    }
}

これでDistinctを使うことができます:

List<LinqTest> uniqueIDs = myList.Distinct().ToList();
52
Rango
myList.GroupBy(i => i.id).Select(group => group.First())
23
Tim Rogers