リストから重複する値を削除する最速の方法は何ですか。List<long> longs = new List<long> { 1, 2, 3, 4, 3, 2, 5 };
したがって、ラムダを使用して重複を削除し、返された : に興味があると仮定します{1, 2, 3, 4, 5}
。あなたの提案は何ですか?
7 に答える
新しいリストを取得する最も簡単な方法は次のとおりです。
List<long> unique = longs.Distinct().ToList();
それで十分ですか、それとも既存のリストを変更する必要がありますか? 後者は、はるかに長い道のりです。
元の順序が維持されることは保証Distinct()
されていませんが、現在の実装では維持されることに注意してください。これが最も自然な実装です。詳細については、Edulinq のブログ記事を参照してください。Distinct()
にする必要がない場合はList<long>
、そのままにしておくことができます:
IEnumerable<long> unique = longs.Distinct();
この時点で、反復するたびに重複除外が実行されunique
ます。それが良いかどうかは、要件によって異なります。
より複雑な型を含む列挙型に対して、この拡張メソッドを使用できます。
IEnumerable<Foo> distinctList = sourceList.DistinctBy(x => x.FooName);
public static IEnumerable<TSource> DistinctBy<TSource, TKey>(
this IEnumerable<TSource> source,
Func<TSource, TKey> keySelector)
{
var knownKeys = new HashSet<TKey>();
return source.Where(element => knownKeys.Add(keySelector(element)));
}
新しいリストを作成するのではなく、元のリストを維持したい場合は、Distinct()
拡張メソッドが内部で行うのと同様のことを行うことができます。つまり、HashSetを使用して一意性をチェックします。
HashSet<long> set = new HashSet<long>(longs.Count);
longs.RemoveAll(x => !set.Add(x));
RemoveAll(predicate)
Listクラスは、述語で指定された条件を満たさないすべての要素を削除するこの便利なメソッドを提供します。述語は、リストの要素タイプのパラメーターを受け取り、bool値を返すデリゲートです。HashSetのAdd()
メソッドは、セットにまだアイテムが含まれていない場合にのみtrueを返します。したがって、セットに追加できないアイテムをリストから削除することで、すべての重複を効果的に削除できます。
Distinct() メソッドがあります。それは動作するはずです。
List<long> longs = new List<long> { 1, 2, 3, 4, 3, 2, 5 };
var distinctList = longs.Distinct().ToList();
List<long> distinctlongs = longs.Distinct().OrderBy(x => x).ToList();
所定の位置に:
public static void DistinctValues<T>(List<T> list)
{
list.Sort();
int src = 0;
int dst = 0;
while (src < list.Count)
{
var val = list[src];
list[dst] = val;
++dst;
while (++src < list.Count && list[src].Equals(val)) ;
}
if (dst < list.Count)
{
list.RemoveRange(dst, list.Count - dst);
}
}