std :: sortおよびstd :: uniqueと同等のC#
質問
C#には整数のリストがあります。重複を削除したいです。 C ++では、std :: sortを実行してからstd :: uniqueアルゴリズムを実行して、一意のリストを非常に効率的に取得します。
C#で同じことを行う最良の方法は何ですか?つまり、次のコードを実行するよりエレガントな方法を探しています。
private static int[] unique(int[] ids)
{
IDictionary<int, object> d = new Dictionary<int, object>();
foreach(int i in ids)
d[i] = null;
int[] results = new int[d.Count];
int j = 0;
foreach(int id in d.Keys)
results[j++] = id;
return results;
}
解決
使用している.NETのバージョンは何ですか?
.NET 3.5では、を呼び出すのと同じくらい簡単です。 Distinct()拡張メソッド、次に ToArray() if本当に再び配列が必要です。
例:
int[] x = new[] { 1, 4, 23, 4, 1 };
int[] distinct = x.Distinct().ToArray();
// distinct is now { 1, 4, 23 } (but not necessarily in that order)
他のヒント
STLメソッドを「非常に効率的」であると考えている場合は、次を使用してください:
var vals = new List<int> { 1, 2, 3, 2, 1, 2, 3, 2, 3, 4, 3, 2, 3 };
vals.Sort();
var uniques = new HashSet<int>(vals);
2.0相当の場合
List<int> vals = new List<int>();
vals.Add(1);
vals.Add(2);
vals.Add(3);
vals.Add(2);
...
vals.Sort();
List<int> uniques = new List<int>();
vals.ForEach(delegate(int v) {
if (!uniques.Contains(v)) uniques.Add(v);
});
.NET 2.0でも、 LINQBridge で同じことができます。これはC#3.0(.NET 2.0でも)で使用する方が簡単ですが、C#2.0および.NET 2.0で使用できるはずです。x.Distinct()ではなくEnumerable.Distinct(x)を使用するだけです。
もちろん、最終的にこれらは以前に投稿したコードの事前にラップされたバージョンであるため(イテレータブロックのようなものを与えたり受けたりする)、そのコードをユーティリティクラスにプッシュして(再)使用することができます
残念ながら、.NET 2.0しか使用できません
中途関連のメモでは、C#には System.Array.Sort コレクションを使用せずに実際の配列をソートするために使用できる静的メソッド。
コレクションの大きさはわかりませんが、数千の整数を扱っていない場合、これで十分かもしれません:
public IEnumerable<int> unique(int[] ids)
{
List<int> l = new List<int>();
foreach (int id in ids)
{
if (!l.Contains(id))
{
l.Add(id);
yield return id;
}
}
}
private static List<T> GetUnique<T>(List<T> list) where T : IEquatable<T>
{
list.Sort();
int count = list.Count;
List<T> unique = new List<T>(count);
T last = default(T);
for (int i = 0; i < count; i++)
{
T val = list[i];
if (i != 0 && last.Equals(val)) continue;
last = val;
unique.Add(val);
}
return unique;
}
所属していません StackOverflow