使用LINQ,从一个列表<int>,我怎么能检索一个列表,包含重复不止一次的条目和他们的值?
当前回答
解决这个问题最简单的方法是根据元素的值对它们进行分组,然后如果组中有多个元素,则选择组中的一个代表。在LINQ中,这转换为:
var query = lst.GroupBy(x => x)
.Where(g => g.Count() > 1)
.Select(y => y.Key)
.ToList();
如果你想知道元素重复了多少次,你可以使用:
var query = lst.GroupBy(x => x)
.Where(g => g.Count() > 1)
.Select(y => new { Element = y.Key, Counter = y.Count() })
.ToList();
这将返回一个匿名类型的List,每个元素将具有element和Counter属性,以检索所需的信息。
最后,如果你要找的是字典,你可以用
var query = lst.GroupBy(x => x)
.Where(g => g.Count() > 1)
.ToDictionary(x => x.Key, y => y.Count());
这将返回一个字典,以您的元素为键,并将其重复的次数作为值。
其他回答
按键删除重复项
myTupleList = myTupleList.GroupBy(tuple => tuple.Item1).Select(group => group.First()).ToList();
只查找重复的值:
var duplicates = list.GroupBy(x => x.Key).Where(g => g.Count() > 1);
E.g.
var list = new[] {1,2,3,1,4,2};
GroupBy将根据它们的键对数字进行分组,并使用它维护计数(重复的次数)。在那之后,我们只是检查重复了不止一次的值。
要查找唯一的值:
var unique = list.GroupBy(x => x.Key).Where(g => g.Count() == 1);
E.g.
var list = new[] {1,2,3,1,4,2};
GroupBy将根据它们的键对数字进行分组,并使用它维护计数(重复的次数)。在此之后,我们只是检查那些只重复一次的值是否惟一。
这是另一种方法:
对于HasDuplicate:
bool hasAnyDuplicate = list.Count > list.Distinct().Count;
对于重复值
List<string> duplicates = new List<string>();
duplicates.AddRange(list);
list.Distinct().ToList().ForEach(x => duplicates.Remove(x));
// for unique duplicate values:
duplicates.Distinct():
所有的GroupBy答案都是最简单的,但不是最有效的。它们对内存性能尤其不利,因为构建大型内部集合需要分配成本。
一个不错的替代方案是HuBeZa的HashSet。基于添加的方法。它表现得更好。
如果你不关心空值,就我所知,像这样的东西是最有效的(CPU和内存):
public static IEnumerable<TProperty> Duplicates<TSource, TProperty>(
this IEnumerable<TSource> source,
Func<TSource, TProperty> duplicateSelector,
IEqualityComparer<TProperty> comparer = null)
{
comparer ??= EqualityComparer<TProperty>.Default;
Dictionary<TProperty, int> counts = new Dictionary<TProperty, int>(comparer);
foreach (var item in source)
{
TProperty property = duplicateSelector(item);
counts.TryGetValue(property, out int count);
switch (count)
{
case 0:
counts[property] = ++count;
break;
case 1:
counts[property] = ++count;
yield return property;
break;
}
}
}
这里的技巧是在重复数达到1时避免额外的查找成本。当然,如果您还想知道每个项重复出现的次数,则可以使用count不断更新字典。对于null,你只需要一些额外的处理,仅此而已。
找出一个枚举对象是否包含任何重复项:
var anyDuplicate = enumerable.GroupBy(x => x.Key).Any(g => g.Count() > 1);
找出一个枚举对象中的所有值是否都是唯一的:
var allUnique = enumerable.GroupBy(x => x.Key).All(g => g.Count() == 1);