代码之家  ›  专栏  ›  技术社区  ›  Paul Hollingsworth

C#等价于std::sort和std::unique

  •  4
  • Paul Hollingsworth  · 技术社区  · 17 年前

    我有一个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;
        }
    
    7 回复  |  直到 12 年前
        1
  •  8
  •   Jon Skeet    17 年前

    什么版本的。你在用NET吗?

    在。NET 3.5,这就像调用 Distinct() 扩展方法,然后 ToArray() 如果你真的需要一个数组。

    例如:

    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)
    
        2
  •  3
  •   Tamir    17 年前

    如果你认为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);
    });
    
        3
  •  1
  •   Marc Gravell    17 年前

    即使是。NET 2.0,你也可以用 LINQBridge 。这将更容易与C#3.0一起使用(即使是.NET 2.0),但应该与C#2.0和.NET 2.0一起使用。NET 2.0-你只需要使用Enumerable。Distinct(x)而不是x.Distinct;

    当然,最终这些只是您之前发布的代码的预包装版本(例如迭代器块),因此您可以将该代码推送到实用程序类中并从那里(重新)使用。

        4
  •  0
  •   Paul Hollingsworth    17 年前

    唉,我只有。NET 2.0可供使用

        5
  •  0
  •   Powerlord    17 年前

    顺便说一句,C#有一个 System.Array.Sort 您可以使用静态方法对实际数组进行排序,而无需使用集合。

        6
  •  0
  •   slf    17 年前

    我不知道你的集合有多大,但如果你不处理数千个整数,这可能就足够了:

    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;
            }
        }
    }
    
        7
  •  0
  •   Cine    16 年前
      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;
      }