6
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【メモ】C#で自作クラスのリストから重複を取り除く簡単な方法

Last updated at Posted at 2021-01-05

自作クラスのリストから重複を取り除きたい

C#にはLinqのDistinctメソッドがある。
これはstring型やint型のリストには有効だが、そのままだと自作クラスでは機能しない。
IEnumerableを実装したクラスまたはIEqualityComparerの実装を作りDistinctメソッドで回すことが定石だが、もっと簡単な方法があったのでメモ φ(・

string型やint型のリストにはDistinctでOK

var array1 = new string[] { "a", "a", "b", "b" };
foreach (var x in array1.Distinct())
    Console.Write(x);
// ab *OK

自作クラスのとき

2021/01/06: コメントを受けて修正済み

var source = new List<M>
{
    new M { P1 = "a", P2 = "a" },
    new M { P1 = "a", P2 = "a" },
    new M { P1 = "b", P2 = "b" },
    new M { P1 = "b", P2 = "c" }
};

var array2 = source.Distinct();
foreach (var x in array2)
    Console.Write($"{{P1: {x.P1}, P2: {x.P2}}}");
// {P1: a, P2: a}{P1: a, P2: a}{P1: b, P2: b}{P1: b, P2: c}
// {P1: a, P2: a} の重複が取り除かれていない

var array3 = source
    .GroupBy(x => new { x.P1, x.P2 })
    .Select(x => x.First());
foreach (var x in array3)
    Console.Write($"{{P1: {x.P1}, P2: {x.P2}}}");
// {P1: a, P2: a}{P1: b, P2: b}{P1: b, P2: c}
// *OK

追記(2021/01/06)

@albireo さんにもっとシンプルな方法で教えてもらいました。
C#7.3からはタプル同士を == != 演算子で比較できるようになったそうです。
サンプルコードはコメントを参照してください。

コメントからの抜粋ですが、

GroupByを使わないと難しいのは、「重複チェックでは対象外のプロパティも重複除外後に参照したい場合」

とのことです :thumbsup:

6
4
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?