에서 LINQ를 사용하여 List<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());
그러면 요소를 키로 사용하고 값으로 반복되는 횟수를 가진 사전을 반환합니다.
답변
열거 형에 중복이 포함되어 있는지 확인하십시오 .
var anyDuplicate = enumerable.GroupBy(x => x.Key).Any(g => g.Count() > 1);
있는지 알아보십시오 모든 열거 가능한의 값은 고유 한 :
var allUnique = enumerable.GroupBy(x => x.Key).All(g => g.Count() == 1);
답변
다른 방법은 HashSet
.
var hash = new HashSet<int>();
var duplicates = list.Where(i => !hash.Add(i));
중복 목록에서 고유 한 값을 원하는 경우 :
var myhash = new HashSet<int>();
var mylist = new List<int>(){1,1,2,2,3,3,3,4,4,4};
var duplicates = mylist.Where(item => !myhash.Add(item)).Distinct().ToList();
다음은 일반적인 확장 방법과 동일한 솔루션입니다.
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 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 moreThan1 = grouped.Where(i => i.IsMultiple());
return moreThan1.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();
}
}
Duplicates 메서드에서 IsMultiple ()을 사용하면 전체 컬렉션을 반복하지 않기 때문에 Count ()보다 빠릅니다.
답변
나는 당신이 당신의 프로젝트에서 그것을 포함 할 수있는 이것에 대한 반응에 대한 확장을 만들었습니다 .List 또는 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
*/
}
답변
중복 값만 찾으려면 다음을 수행하십시오.
var duplicates = list.GroupBy(x => x.Key).Any(g => g.Count() > 1);
예 : var list = new [] {1,2,3,1,4,2};
따라서 group by는 숫자를 키로 그룹화하고 카운트 (반복 횟수)를 유지합니다. 그 후, 우리는 두 번 이상 반복 한 값을 확인하고 있습니다.
uniuqe 값만 찾으려면 다음을 수행하십시오.
var unique = list.GroupBy(x => x.Key).All(g => g.Count() == 1);
예 : var list = new [] {1,2,3,1,4,2};
따라서 group by는 숫자를 키로 그룹화하고 카운트 (반복 횟수)를 유지합니다. 그 후, 우리는 한 번만 반복 한 값이 고유하다는 것을 확인하고 있습니다.
답변
MS SQL Server에서 확인 된 중복 함수의 Linq 대 SQL 확장의 전체 세트. .ToList () 또는 IEnumerable을 사용하지 않습니다. 이러한 쿼리는 메모리가 아닌 SQL Server에서 실행됩니다. . 결과는 메모리에서만 반환됩니다.
public static class Linq2SqlExtensions {
public class CountOfT<T> {
public T Key { get; set; }
public int Count { get; set; }
}
public static IQueryable<TKey> Duplicates<TSource, TKey>(this IQueryable<TSource> source, Expression<Func<TSource, TKey>> groupBy)
=> source.GroupBy(groupBy).Where(w => w.Count() > 1).Select(s => s.Key);
public static IQueryable<TSource> GetDuplicates<TSource, TKey>(this IQueryable<TSource> source, Expression<Func<TSource, TKey>> groupBy)
=> source.GroupBy(groupBy).Where(w => w.Count() > 1).SelectMany(s => s);
public static IQueryable<CountOfT<TKey>> DuplicatesCounts<TSource, TKey>(this IQueryable<TSource> source, Expression<Func<TSource, TKey>> groupBy)
=> source.GroupBy(groupBy).Where(w => w.Count() > 1).Select(y => new CountOfT<TKey> { Key = y.Key, Count = y.Count() });
public static IQueryable<Tuple<TKey, int>> DuplicatesCountsAsTuble<TSource, TKey>(this IQueryable<TSource> source, Expression<Func<TSource, TKey>> groupBy)
=> source.GroupBy(groupBy).Where(w => w.Count() > 1).Select(s => Tuple.Create(s.Key, s.Count()));
}