C#におけるLINQのDistinct()メソッドの特定プロパティに対する使用
LINQのDistinct()メソッドは、シーケンス内の重複する要素を除去して、各要素がシーケンス内で一度だけ出現するようにします。
特定プロパティに対するDistinct()の使用
特定のプロパティに基づいて重複を除去したい場合、Distinct()
メソッドのオーバーロードを使用して、比較のためのセレクター関数を提供します。
例:
var persons = new List<Person>
{
new Person { Name = "Alice", Age = 30 },
new Person { Name = "Bob", Age = 25 },
new Person { Name = "Alice", Age = 30 },
new Person { Name = "Charlie", Age = 30 }
};
var distinctPersonsByName = persons.Distinct(p => p.Name);
このコードでは、Distinct(p => p.Name)
によって、Name
プロパティに基づいて重複を除去しています。つまり、同じ名前を持つPerson
オブジェクトは、結果のシーケンスで一度だけ出現します。
要約
Distinct()
メソッドは、シーケンス内の重複する要素を除去します。- セレクター関数は、比較に使用するプロパティの値を返します。
日本語訳
var persons = new List<Person>
{
new Person { Name = "Alice", Age = 30 },
new Person { Name = "Bob", Age = 25 },
new Person { Name = "Alice", Age = 30 },
new Person { Name = "Charlie", Age = 30 }
};
var distinctPersonsByName = persons.Distinct(p => p.Name);
C#におけるLINQのDistinct()メソッド解説
Distinct()メソッドの基礎
基本的な例:
var numbers = new List<int> { 1, 2, 3, 2, 4, 1 };
var distinctNumbers = numbers.Distinct();
// distinctNumbers: { 1, 2, 3, 4 }
var persons = new List<Person>
{
new Person { Name = "Alice", Age = 30 },
new Person { Name = "Bob", Age = 25 },
new Person { Name = "Alice", Age = 30 },
new Person { Name = "Charlie", Age = 30 }
};
var distinctPersonsByName = persons.Distinct(p => p.Name);
複数のプロパティに基づいて重複を除去するには、匿名型またはTuple
を使用して、複数のプロパティを一つの比較単位として扱います。
var distinctPersonsByNameAndAge = persons.Distinct(p => new { p.Name, p.Age });
このコードでは、Name
とAge
の両方のプロパティが同じであるPerson
オブジェクトが重複とみなされます。
- 複数のプロパティに基づいて重複を除去するには、匿名型または
Tuple
を使用します。
var numbers = new List<int> { 1, 2, 3, 2, 4, 1 };
var distinctNumbers = numbers.Distinct();
// distinctNumbers: { 1, 2, 3, 4 }
var persons = new List<Person>
{
new Person { Name = "Alice", Age = 30 },
new Person { Name = "Bob", Age = 25 },
new Person { Name = "Alice", Age = 30 },
new Person { Name = "Charlie", Age = 30 }
};
var distinctPersonsByName = persons.Distinct(p => p.Name);
var distinctPersonsByNameAndAge = persons.Distinct(p => new { p.Name, p.Age });
LINQのDistinct()メソッドの代替手法
LINQのDistinct()メソッドは、シーケンス内の重複する要素を除去する便利な方法を提供します。しかし、特定のシナリオでは、他のアプローチも検討することができます。
HashSet<T>の使用
HashSet<T>
は、重複しない要素の集合を表します。Add()
メソッドを使用して要素を追加すると、既に存在する要素は無視されます。
var distinctNumbers = new HashSet<int>(numbers);
GroupBy()とFirst()の組み合わせ
GroupBy()
メソッドを使用して、特定のプロパティに基づいて要素をグループ化します。- 各グループの最初の要素を取り出すことで、重複を除去できます。
var distinctPersonsByName = persons.GroupBy(p => p.Name).Select(g => g.First());
カスタム比較器の作成
Distinct()
メソッドのオーバーロードを使用して、カスタム比較器を提供することができます。- 比較器は、要素の比較方法を定義します。
var distinctPersonsByName = persons.Distinct(new PersonNameComparer());
class PersonNameComparer : IEqualityComparer<Person>
{
public bool Equals(Person x, Person y) => x.Name == y.Name;
public int GetHashCode(Person obj) => obj.Name.G etHashCode();
}
ループによる手動チェック
- シンプルなシーケンスに対しては、ループを使用して手動で重複チェックを行うこともできます。
var distinctNumbers = new List<int>();
foreach (var number in numbers)
{
if (!distinctNumbers.Contains(number))
{
distinctNumbers.Add(number );
}
}
選択する手法は、シーケンスのサイズ、パフォーマンス要件、およびコードの読みやすさなどの要因に基づいて決定されます。
var distinctNumbers = new HashSet<int>(numbers);
var distinctPersonsByName = persons.GroupBy(p => p.Name).Select(g => g.First());
var distinctPersonsByName = persons.Distinct(new PersonNameComparer());
class PersonNameComparer : IEqualityComparer<Person>
{
public bool Equals(Person x, Person y) => x.Name == y.Name;
public int GetHashCode(Person obj) => obj.Name.G etHashCode();
}
var distinctNumbers = new List<int>();
foreach (var number in numbers)
{
if (!distinctNumbers.Contains(number))
{
distinctNumbers.Add(number );
}
}
c# linq duplicates