谁有一个快速的方法去重复在c#的泛型列表?
当前回答
可能更简单的方法是确保没有将重复项添加到列表中。
if(items.IndexOf(new_item) < 0)
items.add(new_item)
其他回答
这里有一个扩展的方法来删除相邻的副本原位。首先调用Sort()并传入相同的ic比较器。这应该比Lasse V. Karlsen的版本更有效,后者重复调用RemoveAt(导致多次块内存移动)。
public static void RemoveAdjacentDuplicates<T>(this List<T> List, IComparer<T> Comparer)
{
int NumUnique = 0;
for (int i = 0; i < List.Count; i++)
if ((i == 0) || (Comparer.Compare(List[NumUnique - 1], List[i]) != 0))
List[NumUnique++] = List[i];
List.RemoveRange(NumUnique, List.Count - NumUnique);
}
把它排序,然后检查两个和两个相邻的,因为重复的会聚集在一起。
就像这样:
list.Sort();
Int32 index = list.Count - 1;
while (index > 0)
{
if (list[index] == list[index - 1])
{
if (index < list.Count - 1)
(list[index], list[list.Count - 1]) = (list[list.Count - 1], list[index]);
list.RemoveAt(list.Count - 1);
index--;
}
else
index--;
}
注:
从后到前进行比较,避免每次移除后都要列出度假胜地列表 这个例子现在使用c#值元组来进行交换,如果你不能使用它,可以用适当的代码来代替 最终结果不再排序
这将使用distinct(没有重复元素的元素)并再次将其转换为列表:
List<type> myNoneDuplicateValue = listValueWithDuplicate.Distinct().ToList();
所有的答案要么复制列表,要么创建一个新列表,要么使用慢函数,要么就是慢得令人痛苦。
据我所知,这是我所知道的最快和最便宜的方法(同时,还得到了一个非常有经验的实时物理优化程序员的支持)。
// 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);
}
}
}
推荐文章
- 在每个列表元素上调用int()函数?
- 如何从枚举中选择一个随机值?
- 将Set<T>转换为List<T>的最简洁的方法
- 驻留在App_Code中的类不可访问
- 在链式LINQ扩展方法调用中等价于'let'关键字的代码
- dynamic (c# 4)和var之间的区别是什么?
- Visual Studio: ContextSwitchDeadlock
- 返回文件在ASP。Net Core Web API
- 自定义HttpClient请求头
- 在Python中插入列表的第一个位置
- 如果我使用OWIN Startup.cs类并将所有配置移动到那里,我是否需要一个Global.asax.cs文件?
- VS2013外部构建错误"error MSB4019: The imported project <path> was not found"
- 在javascript中从平面数组构建树数组
- 从另一个列表id中排序一个列表
- 等待一个无效的异步方法