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

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

Например, класс

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

а затем набор типа IEnumerable<Item>

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

Ответы

Ответ 1

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

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

Ответ 2

Кратким решением с одним перечислением будет:

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

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

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

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

Ответ 3

Вы хотите проверить только на 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

Ответ 5

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

x есть true, если list имеет дубликаты.

Ответ 6

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

Пример:

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

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

Ответ 7

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

// 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();

Ответ 8

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);
    }
}

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

Ответ 9

Мы можем удалить повторяющиеся записи, используя .Distinct() в ArrayList.

Пример:

У меня есть столбец createdby в testtable с 5 повторяющимися записями. Я должен получить только одну строку

 ID   Createdby
 ===  ======== 
  1    Reddy
  2    Reddy
  3    Reddy
  4    Reddy

Учитывая приведенную выше таблицу, мне нужно выбрать только один "Reddy"

DataTable table=new DataTable("MyTable");//Actually I am getting this table data from database

DataColumn col=new DataColumn("Createdby");

var  childrows =  table.AsEnumerable().Select( row => row.Field<object>(col)).Distinct().ToArray();