Проверьте IEnumerable для элементов, имеющих повторяющиеся свойства

Как проверить, имеет ли IEnumerable два или более элементов с одинаковым значением свойства ?

например класс

public class Item
{
    public int Prop1 {get;set;}
    public string Prop2 {get;set;}
}

и затем коллекция типа IEnumerable<Item>

мне нужно вернуть false, если в Prop1 есть элементы с повторяющимися значениями.

9 ответов


Я думаю, что этот метод будет работать.

public static bool ContainsDuplicates<T1>(this IEnumerable<T1> source, Func<T1, T2> selector)
{
    var d = new HashSet<T2>();
    foreach(var t in source)
    {
        if(!d.Add(selector(t)))
        {
            return true;
        }
    }
    return false;
}

вы хотите проверить только для Prop1 правильно ?

о:

IEnumerable<Item> items = ...
var noDistinct = items.GroupBy(x => x.Prop1).All(x => x.Count() == 1);
// it returns true if all items have different Prop1, false otherwise

короткое, одно перечисление только решение будет:

public static bool ContainsDuplicates<T>(this IEnumerable<T> list)
    => !list.All(new HashSet<T>().Add);

который можно было бы прочитать как:список нет дублей, когда All элементы могут быть Add - ed к набору.

это концептуально похоже на решение Джейка Пирсона; однако он оставляет независимую концепцию проекции; вопрос OP тогда будет решен как:

items.Select(o => o.Prop1).ContainsDuplicates()


bool x = list.Distinct().SequenceEqual(list);

x is true Если list имеет дубликатов.


вы можете выбрать различные значения из IEnumerable, а затем проверить счетчик на счет полной коллекции.

пример:

var distinctItemCount = myEnumerable.Select(m => m.Prop1).Distinct().Count();

if(distinctItemCount < myEnumerable.Count())
{
 return false;
}

Это может быть сделано для производительности, но это единственный правильный ответ до сих пор.

// Create an enumeration of the distinct values of Prop1
var propertyCollection = objectCollection.Select(o => o.Prop1).Distinct();

// If the property collection has the same number of entries as the object
// collection, then all properties are distinct. Otherwise there are some
// duplicates.
return propertyCollection.Count() == objectCollection.Count();

public static class EnumerableEx
{
    public static IEnumerable<T> GetDuplicates<T>(this IEnumerable<T> source)
    {
        return source.GroupBy(t => t).Where(x => x.Count() > 1).Select(x => x.Key);
    }
}

лично мне нравится аккуратность методов расширения. Если вашим объектам не требуется селектор для определения равенства, то это работает хорошо.


мы можем удалить дубликаты записей с помощью .Distinct() на ArrayList.

пример:

у меня есть