Удаление повторяющихся объектов в списке (С#)
Итак, я понимаю, как удалять дубликаты в списке, когда дело доходит до строк и int и т.д., используя Distinct()
из Linq. Но как удалить дубликаты на основе определенного атрибута объекта?
Например, у меня есть класс TimeMetric
. Этот класс TimeMetric
имеет два атрибута: MetricText
и MetricTime
. У меня есть список TimeMetrics
, называемый MetricList
. Я хочу удалить любые дубликаты TimeMetric
с тем же атрибутом MetricText
. Значение TimeMetric
может быть одинаковым, но если любой TimeMetric
имеет тот же MetricText
, он должен быть не дублирован.
Ответы
Ответ 1
Вам нужно использовать вторую перегрузку Distinct
, которая принимает экземпляр IEqualityComparer<TimeMetric>
в качестве второго параметра. Определите такой компаратор:
class MyComparer : IEqualityComparer<TimeMetric>
{
public bool Equals(TimeMetric x, TimeMetric y)
{
return x.MetricText.Equals(y.MetricText);
}
public int GetHashCode(TimeMetric obj)
{
return obj.MetricText.GetHashCode();
}
}
Важное примечание: Приведенный выше код не проверяет, где свойство MetricText
null
(и похоже, что это возможно, так как это скорее всего string
), Вы должны сделать это и вернуть 0
из GetHashCode
, если MetricText
- null
. С другой стороны, если тип MetricText
является типом значения, вам не нужно выполнять какие-либо изменения.
И затем:
var list = new List<TimeMetric> { ... };
var unique = list.Distinct(new MyComparer());
Ответ 2
Использовать linq:
var list = list
.GroupBy(i => i.MetricText)
.Select(g => g.First())
.ToList();
Или передать в компаратор, который использует свойство:
public class mtCompare : IEqualityComparer<TimeMetric>
{
public bool Equals(TimeMetric x, TimeMetric y)
{
return Equals(x.MetricText, y.MetricText);
}
public int GetHashCode(TimeMetric obj)
{
return obj.MetricText.GetHashCode();
}
}
....
list.Distinct(new mtCompare());
Ответ 3
Вы можете использовать Distinct overload с IEqualityComparer.
Ваш метод equals для вашей реализации IEqualityComparer будет выглядеть следующим образом:
bool Equals(TimeMetric x, TimeMetric y)
{
return x.MetricText.Equals(y.MetricText);
}