У меня есть список предметов.
class Item{
public int Year { get; set; }
public int QuarterIndex { get; set; }
}
Как конвертировать список в отдельный список?
Источник:
List<Item> items = new List<Item>(){
new Item(){ Year = 2013, QuarterIndex = 1},
new Item(){ Year = 2013, QuarterIndex = 2},
new Item(){ Year = 2013, QuarterIndex = 3},
new Item(){ Year = 2013, QuarterIndex = 1}
};
Результат:
target = new List<Item>(){
new Item(){ Year = 2013, QuarterIndex = 1},
new Item(){ Year = 2013, QuarterIndex = 2},
new Item(){ Year = 2013, QuarterIndex = 3}
};
Здесь простой, но потенциально менее эффективный способ, который работает без изменения самого класса:
items = items.GroupBy(i => new { i.Year, i.QuarterIndex })
.Select(g => g.First())
.ToList();
Другой способ - реализовать пользовательский IEqualityComparer<Item>
который вы можете использовать для Distinct
(и других методов в классе Enumerable
):
public class ItemComparer : IEqualityComparer<Item>
{
public bool Equals(Item lhs, Item rhs)
{
if(lhs == null || rhs == null) return false;
return lhs.Year == rhs.Year && lhs.QuarterIndex == rhs.QuarterIndex;
}
public int GetHashCode(Item item)
{
if(item == null) return 0;
unchecked
{
int hash = 23;
hash = (hash * 31) + item.Year;
hash = (hash * 31) + item.QuarterIndex;
return hash;
}
}
}
Теперь это работает:
items = items.Distinct(new ItemComparer()).ToList();
Если вы можете/хотите изменить исходный класс, вы можете переопределить Equals
+ GetHashCode
:
public class Item
{
public int Year { get; set; }
public int QuarterIndex { get; set; }
public override bool Equals(object otherItem)
{
Item other = otherItem as Item;
if (other == null) return false;
return this.Equals(other);
}
public bool Equals(Item otherItem)
{
if(otherItem == null) return false;
return Year == otherItem.Year && QuarterIndex == otherItem.QuarterIndex;
}
public override int GetHashCode()
{
unchecked
{
int hash = 23;
hash = (hash * 31) + Year;
hash = (hash * 31) + QuarterIndex;
return hash;
}
}
}
Затем Distinct
работает "автоматически":
items = items.Distinct().ToList();
.NET Fiddle
? Вот демонстрация ideone с использованием третьего способа: ideone.com/mahzQ0 Вы можете изменить его, чтобы использовать items = items.Distinct(new ItemComparer()).ToList();
продемонстрировать второй подход.
Item
реализующимIEquatable<Item>
; 2) использовать Distinct ()