У меня есть объект с именем "response
" типа <LabelResponse>
, который содержит объект с именем "items
" типа IEnumerable<PostLabelResponse>
. Этот PostLabelResponse
содержит 2 строки с именами "Key
" и "Category
". IEnumerable содержит повторяющиеся значения этого PostLabelResponse
. Как я могу удалить эти дубликаты по значению "Key
" и вернуть "response
"?
Я пробовал с response.items.Distinct()
из LinQ
, но это не сработало
2 ответа
Кажется, что ваш текущий PostLabelResponse
, который, как я предполагаю, выглядит примерно так
public class PostLabelResponse {
...
public string Key {get; set;}
public string Value {get; set;}
...
}
Не предоставляет настраиваемый метод Equals
и GetHashCode
и вот почему .Net использует по умолчанию (которые сравнивают ссылки, а не значения). Если вы хотите сравнить значения, скажем, Key
, а не Value
, вы можете реализовать Equals
и GetHashCode
:
public class PostLabelResponse {
public string Key { get; set; }
public string Value { get; set; }
...
public override bool Equals(object obj) {
if (ReferenceEquals(this, obj))
return true;
return obj is PostLabelResponse other &&
Key == other.Key;
}
public override int GetHashCode() =>
Key?.GetHashCode() ?? 0;
}
С этого момента Distinct()
начинает использовать ваши правила (Equals
и GetHashCode
). Или вы можете реализовать пользовательский компаратор:
public sealed class MyComparer : IEqualityComparer<PostLabelResponse> {
public bool Equals(PostLabelResponse x, PostLabelResponse y) {
if (ReferenceEquals(x, y))
return true;
if (null == x || null == y)
return false;
return (x.Key == y.Key);
}
public int GetHashCode(PostLabelResponse obj) {
return obj?.Key?.GetHashCode() ?? 0;
}
}
Который вы должны указать при использовании Distinct
:
.Distinct(new MyComparer())
Key
.NET 6 представила DistinctBy. метод, который можно использовать для поиска дубликатов на основе определенных свойств, а не всего объекта. В предыдущих версиях тот же метод был доступен в MoreLINQ. библиотека. Вы можете добавить пакет NuGet, но оператор настолько мал, что вы можете легко добавить его в свой проект в качестве исходного кода.
Предполагая, что ваш класс:
public class PostLabelResponse {
...
public string Key {get; set;}
public string Value {get; set;}
...
}
Вы можете получить отдельные объекты с помощью:
var distinct=response.items.DistinctBy(x=>x.Key);
Код оператора очень короткий:
public static IEnumerable<TSource> DistinctBy<TSource, TKey>(
this IEnumerable<TSource> source,
Func<TSource, TKey> keySelector,
IEqualityComparer<TKey>? comparer=null)
{
if (source == null) throw new ArgumentNullException(nameof(source));
if (keySelector == null) throw new ArgumentNullException(nameof(keySelector));
return _(); IEnumerable<TSource> _()
{
var knownKeys = new HashSet<TKey>(comparer);
foreach (var element in source)
{
if (knownKeys.Add(keySelector(element)))
yield return element;
}
}
}
Похожие вопросы
Новые вопросы
c#
C # (произносится как «резкий») - это высокоуровневый, статически типизированный язык программирования с несколькими парадигмами, разработанный Microsoft. Код C # обычно нацелен на семейство инструментов и сред выполнения Microsoft .NET, включая, среди прочего, .NET Framework, .NET Core и Xamarin. Используйте этот тег для вопросов о коде, написанном на C # или в формальной спецификации C #.
PostLabelResponse
равны. Вы можете либо реализовать методыEquals
иGetHashCode
вPostLabelResponse
, либо написать и использовать компаратор, класс, реализующий интерфейсIEqualityComparer<PostLabelResponse>
.