谁有一个快速的方法去重复在c#的泛型列表?


当前回答

使用HashSet: list = new HashSet<T>(list).ToList();

其他回答

如果你使用。net 3+,你可以使用Linq。

List<T> withDupes = LoadSomeData();
List<T> noDupes = withDupes.Distinct().ToList();

根据删除重复,我们必须应用下面的逻辑,所以它将以快速的方式删除重复。

public class Program
{

    public static void Main(string[] arges)
    {
        List<string> cities = new List<string>() { "Chennai", "Kolkata", "Mumbai", "Mumbai","Chennai", "Delhi", "Delhi", "Delhi", "Chennai", "Kolkata", "Mumbai", "Chennai" };
        cities = RemoveDuplicate(cities);

        foreach (var city in cities)
        {
            Console.WriteLine(city);
        }
    }

    public static List<string> RemoveDuplicate(List<string> cities)
    {
        if (cities.Count < 2)
        {
            return cities;
        }

        int size = cities.Count;
        for (int i = 0; i < size; i++)
        {
            for (int j = i+1; j < size; j++)
            {
                if (cities[i] == cities[j])
                {
                    cities.RemoveAt(j);
                    size--;
                    j--;
                }
            }
        }
        return cities;
    }
}

我认为最简单的方法是:

创建一个新列表并添加唯一的项目。

例子:

        class MyList{
    int id;
    string date;
    string email;
    }
    
    List<MyList> ml = new Mylist();

ml.Add(new MyList(){
id = 1;
date = "2020/09/06";
email = "zarezadeh@gmailcom"
});

ml.Add(new MyList(){
id = 2;
date = "2020/09/01";
email = "zarezadeh@gmailcom"
});

 List<MyList> New_ml = new Mylist();

foreach (var item in ml)
                {
                    if (New_ml.Where(w => w.email == item.email).SingleOrDefault() == null)
                    {
                        New_ml.Add(new MyList()
                        {
                          id = item.id,
     date = item.date,
               email = item.email
                        });
                    }
                }

所有的答案要么复制列表,要么创建一个新列表,要么使用慢函数,要么就是慢得令人痛苦。

据我所知,这是我所知道的最快和最便宜的方法(同时,还得到了一个非常有经验的实时物理优化程序员的支持)。

// Duplicates will be noticed after a sort O(nLogn)
list.Sort();

// Store the current and last items. Current item declaration is not really needed, and probably optimized by the compiler, but in case it's not...
int lastItem = -1;
int currItem = -1;

int size = list.Count;

// Store the index pointing to the last item we want to keep in the list
int last = size - 1;

// Travel the items from last to first O(n)
for (int i = last; i >= 0; --i)
{
    currItem = list[i];

    // If this item was the same as the previous one, we don't want it
    if (currItem == lastItem)
    {
        // Overwrite last in current place. It is a swap but we don't need the last
       list[i] = list[last];

        // Reduce the last index, we don't want that one anymore
        last--;
    }

    // A new item, we store it and continue
    else
        lastItem = currItem;
}

// We now have an unsorted list with the duplicates at the end.

// Remove the last items just once
list.RemoveRange(last + 1, size - last - 1);

// Sort again O(n logn)
list.Sort();

最终成本为:

nlogn + n + nlogn = n + 2nlogn = O(nlogn)非常漂亮。

关于RemoveRange注意事项: 由于我们不能设置列表的计数并避免使用Remove函数,我不知道这个操作的确切速度,但我猜这是最快的方法。

我有我自己的方式。我是2循环相同的列表比较列表项。然后去掉第二个。

            for(int i1 = 0; i1 < lastValues.Count; i1++)
            {
                for(int i2 = 0; i2 < lastValues.Count; i2++)
                {
                    if(lastValues[i1].UserId == lastValues[i2].UserId)
                    {
                        lastValues.RemoveAt(i2);
                    }
                }
            }