2013-08-26 3 views
-1

У меня есть класс Элементы со свойствами (Id, Name, DrugCode1, DrugCode2).Удалить дубликат из следующего списка, используя Linq

Список предметов заполнен дублируемыми элементами.

Для например .:

------------------------------------------ 
Id  Name  DrugCode1 DrugCode2 
------------------------------------------ 
1   Item1  2   3 
2   Item2  3   2 
3   Item3  4   3 
1   Item1  3   2 
3   Item3  3   4 

Если DurgCode1 и DrugCode2 перепутаны, то мы рассмотрим элементы дубликатами

например:

1   Item1  2   3 
1   Item1  3   2 

Вышеприведенные 2 Itmes считаются дубликатом поскольку DrugCode1 и DrugCode2 меняются на противоположные. Нам просто нужно извлечь только один элемент.

Как удалить дубликаты в списке с помощью linq?

+0

возможно дубликат [Как использовать LINQ Distinct() с несколькими полями] (HTTP : //stackoverflow.com/questions/10719928/how-to-use-linq-distinct-with-multiple-fields) –

+3

LINQ to _what_? –

+1

Как насчет 'Item3'? Он также появляется два раза, с кодами '4,3' и' 3,4' ... – Shaamaan

ответ

0

Enumerable.Distinct имеет перегрузку, которая принимает пользовательский параметр IEqualityComparer. Передайте функцию, которая обрабатывает два предмета как равные, если их наркотические коды совпадают в любом порядке.

3

Поскольку вы не отметили поставщика linq, я предполагаю, что Linq-To-Objects. Вы можете использовать анонимный тип в том же порядке для GroupBy:

IEnumerable<Item> distinctItems = items 
    .GroupBy(i => new { Min=Math.Min(i.DrugCode1, i.DrugCode2),Max=Math.Max(i.DrugCode1, i.DrugCode2) }) 
    .Select(g => g.First()); 
3

LINQ Distinct допускает IEqualityComparer<T> в качестве параметра. Выбирая этот путь, вы можете реализовать свой собственный IEqualityComparer как это:

class ItemEqualityComparer : IEqualityComparer<Item> 
{ 

    public bool Equals(Item i1, Item i2) 
    { 
     if (i1.ID == i2.ID && i1.Name == i2.Name && 
      (i1.DrugCode1 == i2.DrugCode1 || i1.DrugCode1 == i2.DrugCode2 ||  
      i1.DrugCode2 == i2.DrugCode1)) 
     { 
      return true; 
     } 
     else 
     { 
      return false; 
     } 
    } 

    public int GetHashCode(Item obj) 
    { 
     int hash = 13; 
     int min = Math.Min(obj.DrugCode1, obj.DrugCode2); 
     int max = Math.Max(obj.DrugCode1, obj.DrugCode2); 
     hash = (hash * 7) + min; 
     hash = (hash * 7) + max; 
     return hash; 
    } 
} 

Теперь вы можете использовать:

var cleanList = listOfItems.Distinct(new ItemEqualityComparer()); 

Это немного больше, чем лямбда-выражения, но это чистый, простой и повторно годные к употреблению.

Пожалуйста, проверьте имя класса (Элементы должны быть элементами).

0

Вы можете написать IEqaulityComparer, а затем использовать его с Distinct

class ItemEuqalityComprer : IEqualityComparer<Item> 
{ 
    public bool Equals(Item x, Item y) 
    { 
     return x.DrugCode1 == y.DrugCode2 
       && x.DrugCode2 == y.DrugCode1; 
    } 

    public int GetHashCode(Item obj) 
    { 
     return obj.Id == null ? 0 : obj.Id.GetHashCode(); 
    } 
} 

Использование с Distinct:

 var item1 = new Item {DrugCode1 = "2", DrugCode2 = "3"}; 
     var item2 = new Item {DrugCode1 = "3", DrugCode2 = "2"}; 
     var item3 = new Item { DrugCode1 = "3", DrugCode2 = "4" }; 
     var items = new[] {item1, item2, item3}; 

     var distincts = items.Distinct(new ItemEuqalityComprer()); 
Смежные вопросы