使用LINQ,從List<int>
,如何檢索包含重複多次重複的條目及其值的列表?C#LINQ在列表中找到重複項
回答
解決問題的最簡單方法是根據元素的值對元素進行分組,然後在組中有多個元素時選擇該組的代表。在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();
這將返回一個匿名類型的列表,每個元素將具有元素和計數器的屬性,以檢索您需要的信息。
最後,如果它是你正在尋找一個字典,你可以使用
var query = lst.GroupBy(x=>x)
.Where(g=>g.Count()>1)
.ToDictionary(x=>x.Key,y=>y.Count());
這將返回一個字典,用你的元素作爲重點,與時代它的重複值的數量。
你可以這樣做:
var list = new[] {1,2,3,1,4,2};
var duplicateItems = list.Duplicates();
有了這些擴展方法:
public static class Extensions
{
public static IEnumerable<TSource> Duplicates<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> selector)
{
var grouped = source.GroupBy(selector);
var moreThen1 = grouped.Where(i => i.IsMultiple());
return moreThen1.SelectMany(i => i);
}
public static IEnumerable<TSource> Duplicates<TSource, TKey>(this IEnumerable<TSource> source)
{
return source.Duplicates(i => i);
}
public static bool IsMultiple<T>(this IEnumerable<T> source)
{
var enumerator = source.GetEnumerator();
return enumerator.MoveNext() && enumerator.MoveNext();
}
}
在重複的方法使用IsMultiple()的速度更快,然後計數(),因爲這不遍歷整個集合。
如果你看[分組的參考源](http://referencesource.microsoft.com/System.Core/System/Linq/Enumerable.cs.html#2177),你可以看到'Count()'**是**預先計算的,您的解決方案可能會更慢。 – Johnbot
@Johnbot。你是對的,在這種情況下,它更快,實現可能永遠不會改變......但它取決於IGrouping背後的實現類的實現細節。用我的實現,你知道它永遠不會迭代整個集合。 –
因此計數['Count()']與迭代整個列表基本上不同。 Count()是預先計算的,但是迭代整個列表不是。 – Jogi
另一種方法是使用HashSet
:
var hash = new HashSet<int>();
var duplicates = list.Where(i => !hash.Add(i));
這裏是相同的解決方案作爲一種通用的擴展方法:
public static class Extensions
{
public static IEnumerable<TSource> GetDuplicates<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> selector, IEqualityComparer<TKey> comparer)
{
var hash = new HashSet<TKey>(comparer);
return source.Where(item => !hash.Add(selector(item))).ToList();
}
public static IEnumerable<TSource> GetDuplicates<TSource>(this IEnumerable<TSource> source, IEqualityComparer<TSource> comparer)
{
return source.GetDuplicates(x => x, comparer);
}
public static IEnumerable<TSource> GetDuplicates<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> selector)
{
return source.GetDuplicates(selector, null);
}
public static IEnumerable<TSource> GetDuplicates<TSource>(this IEnumerable<TSource> source)
{
return source.GetDuplicates(x => x, 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);
謝謝,它正在工作 – Ilaria
我創建了一個extention來響應這個你可以includ它在你的項目,我認爲當您搜索列表或重複這個返回最案LINQ。
例子:
//Dummy class to compare in list
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
public string Surname { get; set; }
public Person(int id, string name, string surname)
{
this.Id = id;
this.Name = name;
this.Surname = surname;
}
}
//The extention static class
public static class Extention
{
public static IEnumerable<T> getMoreThanOnceRepeated<T>(this IEnumerable<T> extList, Func<T, object> groupProps) where T : class
{ //Return only the second and next reptition
return extList
.GroupBy(groupProps)
.SelectMany(z => z.Skip(1)); //Skip the first occur and return all the others that repeats
}
public static IEnumerable<T> getAllRepeated<T>(this IEnumerable<T> extList, Func<T, object> groupProps) where T : class
{
//Get All the lines that has repeating
return extList
.GroupBy(groupProps)
.Where(z => z.Count() > 1) //Filter only the distinct one
.SelectMany(z => z);//All in where has to be retuned
}
}
//how to use it:
void DuplicateExample()
{
//Populate List
List<Person> PersonsLst = new List<Person>(){
new Person(1,"Ricardo","Figueiredo"), //fist Duplicate to the example
new Person(2,"Ana","Figueiredo"),
new Person(3,"Ricardo","Figueiredo"),//second Duplicate to the example
new Person(4,"Margarida","Figueiredo"),
new Person(5,"Ricardo","Figueiredo")//third Duplicate to the example
};
Console.WriteLine("All:");
PersonsLst.ForEach(z => Console.WriteLine("{0} -> {1} {2}", z.Id, z.Name, z.Surname));
/* OUTPUT:
All:
1 -> Ricardo Figueiredo
2 -> Ana Figueiredo
3 -> Ricardo Figueiredo
4 -> Margarida Figueiredo
5 -> Ricardo Figueiredo
*/
Console.WriteLine("All lines with repeated data");
PersonsLst.getAllRepeated(z => new { z.Name, z.Surname })
.ToList()
.ForEach(z => Console.WriteLine("{0} -> {1} {2}", z.Id, z.Name, z.Surname));
/* OUTPUT:
All lines with repeated data
1 -> Ricardo Figueiredo
3 -> Ricardo Figueiredo
5 -> Ricardo Figueiredo
*/
Console.WriteLine("Only Repeated more than once");
PersonsLst.getMoreThanOnceRepeated(z => new { z.Name, z.Surname })
.ToList()
.ForEach(z => Console.WriteLine("{0} -> {1} {2}", z.Id, z.Name, z.Surname));
/* OUTPUT:
Only Repeated more than once
3 -> Ricardo Figueiredo
5 -> Ricardo Figueiredo
*/
}
考慮使用Skip(1).Any()而不是Count()。如果您有1000個重複項,則Skip(1).Any()會在找到第二個重複項後停止。 Count()將訪問所有1000個元素。 –
如果您添加此擴展方法,請考慮使用HashSet.Add而不是GroupBy,正如在其他答案中提到的那樣。只要HashSet.Add發現重複,它就會停止。您的GroupBy將繼續對所有元素進行分組,即使已找到具有多個元素的組 –
全套[重複] LINQ的擴展與MS SQL Server檢出的
public static class LinqExtensions {
public class CounterOfT<T> {
public T Key { get; set; }
public int Count { get; set; }
}
public static IQueryable<TKey> Duplicates<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> groupBy) where TSource : class
=> source.GroupBy(groupBy).Where(w => w.Count() > 1).Select(s => s.Key).AsQueryable();
public static IQueryable<TSource> GetDuplicates<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> groupBy) where TSource : class
=> source.GroupBy(groupBy).Where(w => w.Count() > 1).SelectMany(s => s).AsQueryable();
public static IQueryable<CounterOfT<TKey>> DuplicatesCounts<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> groupBy) where TSource : class
=> source.GroupBy(groupBy).Where(w => w.Count() > 1).Select(y => new CounterOfT<TKey> { Key = y.Key, Count = y.Count() }).AsQueryable();
public static IQueryable<Tuple<TKey, int>> DuplicatesCountsAsTuble<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> groupBy) where TSource : class
=> source.GroupBy(groupBy).Where(w => w.Count() > 1).Select(s => Tuple.Create(s.Key, s.Count())).AsQueryable();
}
- 1. 在列表中選擇重複項linq
- 2. c#從列表中找到linq到列表中的項目
- 3. 刪除列表中的重複項-linq
- 4. 使用linq查找多個列表中的重複項
- 5. C#的LINQ找到重複的行
- 6. LINQ組項目到匿名類型列表,其中重複
- 7. 找到固定項目重複列表中的第n項
- 8. 在列表中找到重複項並添加它們的值
- 9. 如何在列表<>中找到重複的項目?
- 10. 在整數列表中找到重複項
- 11. 使用Linq找到C#通用列表中的最新項目
- 12. 從C++列表中刪除重複項
- 13. 刪除列表中的重複項(c#)
- 14. LINQ C#組合列表,刪除重複項
- 15. C#的LINQ - 在列表中查找重複的值,然後選擇它的id
- 16. 如何在列表中找到重複項而不創建單獨的列表?
- 17. MySQL在多列中查找重複項
- 18. 在列表中查找項目和重複項
- 19. 重複列表中的重複項
- 20. 在列表中查找重複項,包括排列
- 21. python在列表中找到重複列表
- 22. 查找重複項C#
- 23. 使用LINQ查找/刪除重複項
- 24. 列表中的重複項
- 25. 如何在MySQL中找到重複項
- 26. 如何在NSMutableDictionary中找到重複項?
- 27. 如何在列表中找到重複項,並刪除除特定項之外的所有重複項?
- 28. 在列表中找到重複項並根據其他字段排除項目
- 29. C#列表中的重複
- 30. C#查找列表是否包含重複5次的項目
謝謝你,現在我很清楚LINQ是如何工作的,有一個愉快的一天。 –
現在只是一個奇蹟,假設重複的int分佈到n個int數組中,我使用dictionary和for循環來理解哪個數組包含重複項並根據分佈邏輯將其刪除,是否有最快的方法(linq想知道)取得這樣的結果?預先感謝你的興趣。 –
我做這樣的事情: 'code' 對(INT I = 0;我()); 對(INT K = 0; k