Usuwanie duplikatów z listy za pomocą linq
Mam klasę Items
z properties (Id, Name, Code, Price)
.
Lista Items
jest wypełniona duplikowanymi elementami.
Dla ex.:
1 Item1 IT00001 $100
2 Item2 IT00002 $200
3 Item3 IT00003 $150
1 Item1 IT00001 $100
3 Item3 IT00003 $150
Jak usunąć duplikaty z listy za pomocą linq?
10 answers
var distinctItems = items.Distinct();
Aby dopasować tylko niektóre właściwości, utwórz własną porównywarkę równości, np.:
class DistinctItemComparer : IEqualityComparer<Item> {
public bool Equals(Item x, Item y) {
return x.Id == y.Id &&
x.Name == y.Name &&
x.Code == y.Code &&
x.Price == y.Price;
}
public int GetHashCode(Item obj) {
return obj.Id.GetHashCode() ^
obj.Name.GetHashCode() ^
obj.Code.GetHashCode() ^
obj.Price.GetHashCode();
}
}
Następnie użyj go w ten sposób:
var distinctItems = items.Distinct(new DistinctItemComparer());
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-10-22 12:10:59
var distinctItems = items.GroupBy(x => x.Id).Select(y => y.First());
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-04-12 06:46:30
Jeśli jest coś, co odrzuca Twoje odrębne zapytanie, możesz spojrzeć na MoreLinq i użyć operatora DistinctBy i wybrać różne obiekty według id.
var distinct = items.DistinctBy( i => i.Id );
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-10-22 12:00:16
W ten sposób udało mi się grupować z Linq. Mam nadzieję, że to pomoże.
var query = collection.GroupBy(x => x.title).Select(y => y.FirstOrDefault());
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-19 07:43:52
Użyj Distinct()
ale pamiętaj, że używa domyślnego porównywania równości do porównywania wartości, więc jeśli chcesz czegoś więcej, musisz zaimplementować swój własny porównywanie.
Zobacz http://msdn.microsoft.com/en-us/library/bb348436.aspx na przykład.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-03-05 19:25:00
Masz tutaj trzy opcje usuwania zduplikowanego elementu na liście:
- Użyj niestandardowego porównywania równości, a następnie użyj
Distinct(new DistinctItemComparer())
jako @Christian Hayter . -
Użyj
GroupBy
, ale zauważ, że wGroupBy
powinieneś grupować według wszystkich kolumn, ponieważ jeśli po prostu grupujesz wedługId
nie zawsze usuwa się zduplikowane elementy. Na przykład rozważ następujący przykład:List<Item> a = new List<Item> { new Item {Id = 1, Name = "Item1", Code = "IT00001", Price = 100}, new Item {Id = 2, Name = "Item2", Code = "IT00002", Price = 200}, new Item {Id = 3, Name = "Item3", Code = "IT00003", Price = 150}, new Item {Id = 1, Name = "Item1", Code = "IT00001", Price = 100}, new Item {Id = 3, Name = "Item3", Code = "IT00003", Price = 150}, new Item {Id = 3, Name = "Item3", Code = "IT00004", Price = 250} }; var distinctItems = a.GroupBy(x => x.Id).Select(y => y.First());
Wynik dla tej grupy będzie:
{Id = 1, Name = "Item1", Code = "IT00001", Price = 100} {Id = 2, Name = "Item2", Code = "IT00002", Price = 200} {Id = 3, Name = "Item3", Code = "IT00003", Price = 150}
Który jest niepoprawne, ponieważ uważa
{Id = 3, Name = "Item3", Code = "IT00004", Price = 250}
za duplikat. Więc poprawne zapytanie brzmiałoby:var distinctItems = a.GroupBy(c => new { c.Id , c.Name , c.Code , c.Price}) .Select(c => c.First()).ToList();
3.Override
Equal
andGetHashCode
in item class:public class Item { public int Id { get; set; } public string Name { get; set; } public string Code { get; set; } public int Price { get; set; } public override bool Equals(object obj) { if (!(obj is Item)) return false; Item p = (Item)obj; return (p.Id == Id && p.Name == Name && p.Code == Code && p.Price == Price); } public override int GetHashCode() { return String.Format("{0}|{1}|{2}|{3}", Id, Name, Code, Price).GetHashCode(); } }
Wtedy możesz użyć go tak:
var distinctItems = a.Distinct();
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:18:13
List<Employee> employees = new List<Employee>()
{
new Employee{Id =1,Name="AAAAA"}
, new Employee{Id =2,Name="BBBBB"}
, new Employee{Id =3,Name="AAAAA"}
, new Employee{Id =4,Name="CCCCC"}
, new Employee{Id =5,Name="AAAAA"}
};
List<Employee> duplicateEmployees = employees.Except(employees.GroupBy(i => i.Name)
.Select(ss => ss.FirstOrDefault()))
.ToList();
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-18 08:30:00
Wypróbuj tę metodę rozszerzenia. Mam nadzieję, że to pomoże.
public static class DistinctHelper
{
public static IEnumerable<TSource> DistinctBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
{
var identifiedKeys = new HashSet<TKey>();
return source.Where(element => identifiedKeys.Add(keySelector(element)));
}
}
Użycie:
var outputList = sourceList.DistinctBy(x => x.TargetProperty);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-21 16:52:34
Uniwersalna metoda rozszerzenia:
public static class EnumerableExtensions
{
public static IEnumerable<T> DistinctBy<T, TKey>(this IEnumerable<T> enumerable, Func<T, TKey> keySelector)
{
return enumerable.GroupBy(keySelector).Select(grp => grp.First());
}
}
Przykład użycia:
var lstDst = lst.DistinctBy(g => g.Key);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-14 11:24:35
Gdy nie chcesz pisać Ieequalitycomparer możesz spróbować czegoś takiego jak following.
class Program
{
private static void Main(string[] args)
{
var items = new List<Item>();
items.Add(new Item {Id = 1, Name = "Item1"});
items.Add(new Item {Id = 2, Name = "Item2"});
items.Add(new Item {Id = 3, Name = "Item3"});
//Duplicate item
items.Add(new Item {Id = 4, Name = "Item4"});
//Duplicate item
items.Add(new Item {Id = 2, Name = "Item2"});
items.Add(new Item {Id = 3, Name = "Item3"});
var res = items.Select(i => new {i.Id, i.Name})
.Distinct().Select(x => new Item {Id = x.Id, Name = x.Name}).ToList();
// now res contains distinct records
}
}
public class Item
{
public int Id { get; set; }
public string Name { get; set; }
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-06 06:33:47