Отличный список объектов на основе произвольного ключа в LINQ

Убедитесь, что вы установили NumPy для Python 3, возможно, вы использовали установку для Python 2 в своем предыдущем коде. Надеюсь, это поможет

12
задан Sam Saffron 13 April 2009 в 00:18
поделиться

4 ответа

Очень элегантный и намеренный способ раскрытия намерений - определить новый метод расширения в IEnumerable

Итак, у вас есть:

list = list.Distinct(foo => foo.id).ToList();

И ...

    public static IEnumerable<T> Distinct<T,TKey>(this IEnumerable<T> list, Func<T,TKey> lookup) where TKey : struct {
        return list.Distinct(new StructEqualityComparer<T, TKey>(lookup));
    }


    class StructEqualityComparer<T,TKey> : IEqualityComparer<T> where TKey : struct {

        Func<T, TKey> lookup;

        public StructEqualityComparer(Func<T, TKey> lookup) {
            this.lookup = lookup;
        }

        public bool Equals(T x, T y) {
            return lookup(x).Equals(lookup(y));
        }

        public int GetHashCode(T obj) {
            return lookup(obj).GetHashCode();
        }
    }

Подобный вспомогательный класс может быть построен для сравнения объектов. (Это должно будет сделать лучшую обработку нуля)

23
ответ дан 2 December 2019 в 03:38
поделиться

Использование метода Distinct () примерно в 4 раза быстрее, чем использование GroupBy () в моем неофициальном тесты. На 1 млн. Foo мой тест имеет Distinct () примерно за 0,89 секунды, чтобы создать уникальный массив из неуникального массива, где GroupBy () занимает около 3,4 секунды.

Мой вызов Distinct () выглядит так,

var unique = list.Distinct(FooComparer.Instance).ToArray();

и FooComparer выглядит,

class FooComparer : IEqualityComparer<Foo> {
    public static readonly FooComparer Instance = new FooComparer();

    public bool Equals(Foo x, Foo y) {
        return x.id.Equals(y.id);
    }

    public int GetHashCode(Foo obj) {
        return obj.id.GetHashCode();
    }
}

и моя версия GroupBy () выглядит,

var unique = (from l in list group l by l.id into g select g.First()).ToArray();
15
ответ дан 2 December 2019 в 03:38
поделиться

Создайте IEqualityComparer , который возвращает true, если поля идентификатора совпадают, и передать это оператору Distinct ().

1
ответ дан 2 December 2019 в 03:38
поделиться
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            var list = new List<Foo>();
            list.Add(new Foo() { id = Guid.Empty, description = "empty" });
            list.Add(new Foo() { id = Guid.Empty, description = "empty" });
            list.Add(new Foo() { id = Guid.NewGuid(), description = "notempty" });
            list.Add(new Foo() { id = Guid.NewGuid(), description = "notempty2" });

            var unique = from l in list
                         group l by new { l.id, l.description } into g
                         select g.Key;
            foreach (var f in unique)
                Console.WriteLine("ID={0} Description={1}", f.id,f.description);
            Console.ReadKey(); 
        }
    }

    class Foo
    {
        public Guid id;
        public string description;
    }
}
1
ответ дан 2 December 2019 в 03:38
поделиться
Другие вопросы по тегам:

Похожие вопросы: