【发布时间】:2017-12-18 17:55:21
【问题描述】:
我知道关于这个主题有很多类似的问题,但我找不到我正在寻找的答案。这是我的要求。
我有一长串字符串(很容易超过 50,000 甚至 100K 项),我需要在其中找到重复项。但是仅仅查找重复项是行不通的;我真正想做的是遍历列表并在每个项目的末尾添加一个增量索引以指示项目重复的次数。为了更好地说明,让我举个例子。我的列表实际上包含路径,所以示例大致类似。
我原来的列表:
AAA\BBB
AAA\CCC
AAA\CCC
BBB\XXX
BBB
BBB\XXX
BBB\XXX
添加了索引的调整列表:
AAA\BBB[1]
AAA\CCC[1]
AAA\CCC[2]
BBB\XXX[1]
BBB[1]
BBB\XXX[2]
BBB\XXX[3]
首先我使用 Linq 尝试了以下方法:
List<string> originalList = new List<string>();
List<string> duplicateItems = new List<string>();
// pathList is a simple List<string> that contains my paths.
foreach (string item in pathList)
{
// Do some stuff here and pick 'item' only if it fits some criteria.
if (IsValid(item))
{
originalList.Add(item);
int occurences = originalList.Where(x => x.Equals(item)).Count();
duplicateItems.Add(item + "[" + occurences + "]");
}
}
这工作得很好,给了我想要的结果。问题是考虑到我的列表可以包含 10 万个项目,它的速度非常慢。所以我环顾四周,了解到 HashSet 可能是一种可能更有效的替代方案。但我不太清楚如何使用它来获得我想要的结果。
我想我可以试试这样的:
HashSet<string> originalList = new HashSet<string>();
List<string> duplicateItems = new List<string>();
foreach (string item in pathList)
{
// Do some stuff here and pick 'item' only if it fits some criteria.
if (IsValid(item))
{
if (!originalList.Add(item))
{
duplicateItems.Add(item + "[" + ??? + "]");
}
}
}
稍后我可以将“[1]”添加到 HashSet 中的所有项目,但是如何在将项目添加到我的重复列表时正确地获得索引(上面标有通用混淆符号,???) ?我无法保留可以传递给我的方法的引用 int,因为可能有数百个不同的重复项,每个重复的次数都不同,如我的示例所示。
我还能使用 HashSet,还是有更好的方法来实现我的目标?即使是指向正确方向的轻微指针也会有很大帮助。
【问题讨论】:
-
你想把它们都打到最后吗?
-
最好,是的。但如果它不是太慢且列表不是太多,我也会考虑其他替代方案。
-
结果列表中元素的顺序重要吗?
-
您不能将
HashSet<string>用于原始列表,因为HashSet<T>不存储重复项。 -
@NineBerry 不,它没有。
标签: c# list linq duplicates hashset