私はクラスのクラスリストを持っています
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
の繰り返しがある場合、結果は最初の出現のみを取るべきです。
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
を使って作業するのが良いのか、それをList
、Set
、Dictionary
にするのか、それともnotnotにするのが良いのかを判断する必要があります。
morelinq を使用すると、DistinctBy
を使用できます。
myList.DistinctBy(x => x.id);
それ以外の場合は、グループを使用できます。
myList.GroupBy(x => x.id)
.Select(g => g.First());
この場合はIDを比較するために、Equals
とGetHashCode
を有意に上書きする必要があります。
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();
myList.GroupBy(i => i.id).Select(group => group.First())