Как получить отдельный список из списка объектов? - PullRequest
41 голосов
/ 14 февраля 2011

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

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

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

Ответы [ 7 ]

88 голосов
/ 14 февраля 2011

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

someList.GroupBy(elem=>elem.Prop2).Select(group=>group.First());
48 голосов
/ 14 февраля 2011

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

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

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

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

19 голосов
/ 14 февраля 2011

вам нужно использовать .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());
12 голосов
/ 28 января 2017

Переопределить Равно (объект obj) и 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();
2 голосов
/ 14 февраля 2011

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

1 голос
/ 30 марта 2018

Seven. Годы. Позже.

Я знаю, что это было давно, но мне нужен был самый простой ответ, и на данный момент (с .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.

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

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

IEnumerable <long> allIds = allFileModel.Select(fm => fm.groupId).Distinct();
0 голосов
/ 28 июня 2018

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

Первый, включая библиотеку

using Microsoft.Ajax.Utilities;

тогда

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