it-swarm-ru.tech

Как получить отдельный список из списка объектов?

У меня есть List<MyClass> someList.

class MyClass
{
    public int Prop1...
    public int Prop2...
    public int Prop3...
}

Я хотел бы знать, как получить новый отличный List<MyClass> distinctList от List<MyClass> someList, но только сравнивая его с Prop2.

37
Willem

К сожалению, в фреймворке нет действительно простой встроенной поддержки для этого - но вы можете использовать DistinctBy реализацию, которую я имею в MoreLINQ .

Вы бы использовали:

var distinctList = someList.DistinctBy(x => x.Prop2).ToList();

(Вы можете взять только реализацию DistinctBy. Если вы предпочитаете использовать реализацию Microsoft, я думаю, что в System.Interactive Assembly из Reactive Extensions . Есть что-то похожее.)

41
Jon Skeet

Вы можете эмулировать эффект DistinctBy, используя GroupBy, а затем просто используя первую запись в каждой группе. Может быть немного медленнее, чем в других реализациях.

someList.GroupBy(elem=>elem.Prop2).Select(group=>group.First());
79
CodesInChaos

вам нужно использовать метод расширения .Distinct(..); .. Вот небольшой пример:

public class Comparer : IEqualityComparer<Point>
    {
        public bool Equals(Point x, Point y)
        {
            return x.X == y.X;
        }

        public int GetHashCode(Point obj)
        {
            return (int)obj.X;
        }
    }

Не забывайте о GetHashCode.

Использование:

List<Point> p = new List<Point>();
// add items
p.Distinct(new Comparer());
19
Ilya Smagin

Переопределить равно (объектный объект) и GetHashCode () методы:

class MyClass
{
    public int Prop1 { get; set; }
    public int Prop2 { get; set; }
    public int Prop3 { get; set; }

    public override bool Equals(object obj)
    {
        return ((MyClass)obj).Prop2 == Prop2;
    }
    public override int GetHashCode()
    {
        return Prop2.GetHashCode();
    }
}

а затем просто позвоните:

List<MyClass> distinctList = someList.Distinct().ToList();
11
Waldemar Gałęzinowski

Создайте класс, который реализует интерфейс IEqualityComparer , который проверяет только ваше свойство Prop2. Затем вы можете передать экземпляр этого класса методу расширения Distinct.

2
Christian

Семь. Годы. Потом.

Я знаю, что прошло какое-то время, но мне нужен был самый простой ответ, и в настоящее время (с .NET 4.5.1) я обнаружил, что следующий ответ является наиболее прямым ответом, который я мог получить:

IEnumerable<long> allIds = waitingFiles.Values.Select(wf => wf.groupId).Distinct();

Моя ситуация такова, что у меня есть ConcurrentDictionary, который выглядит примерно так: ConcurrentDictionary<long, FileModel>

Свойство ConcurrentDictionary Values ​​в основном является моим List<FileModel>.

* FileModel имеет идентификатор группы, который не обязательно уникален (хотя, очевидно, ключ (длинный), который я использую для добавления объекта FileModel в словарь, уникален для FileModel).

* Назван для ясности в примере.

Дело в том, что у меня есть большое количество FileModels (представьте 100) в ConcurrentDictionary, и в этих 100 FileModels есть 5 разных groupIds.

На данный момент мне просто нужен список различных groupId.

Итак, еще раз, если бы у меня был только список FileModel, код выглядел бы следующим образом:

IEnumerable <long> allIds = allFileModel.Select(fm => fm.groupId).Distinct();
1
raddevus

Просто используйте встроенную функцию DistinctBy из библиотеки Microsoft Ajax Utility, как пример:

Сначала включая библиотеку

using Microsoft.Ajax.Utilities;

затем

var distinctList = yourList.DistinctBy(x => x.Prop2).ToList();
0
Anh Hoang