Find Max / Min Element Without Using IComparable <T>

Say I have the following:

public Class BooClass
{
   public int field1;
   public double field2;
   public DateTime field3;
}

public List<BooClass> booList;

So, for example, how to get the element with the earliest time in field3 using booList.Find ()

Modify my apologies, I wanted to make all fields public for the sake of simplicity. I know that I can do this in linq, I wondered if there is one simple condition for the Find method.

+5
source share
5 answers

F # has convenient operators minByand maxBywhich I like to implement as C # extension methods, since the Linq library skips them. This is a little work, but only a little, and this avoids complex expressions such as

var earliest = booList.First(b => b.Field3 == booList.Min(e => e.Field3));

Instead, you can enter the following:

var earliest = booList.MinBy(b => b.Field3);

Simple implementation:

static T MinBy<T, C>(this IEnumerable<T> sequence, Func<T, C> keySelector)
{
    bool first = true;
    T result = default(T);
    C minKey = default(C);
    IComparer<C> comparer = Comparer<C>.Default; //or you can pass this in as a parameter

    foreach (var item in sequence)
    {
        if (first)
        {
            result = item;
            minKey = keySelector.Invoke(item);
            first = false;
            continue;
        }

        C key = keySelector.Invoke(item);
        if (comparer.Compare(key, minKey) < 0)
        {
            result = item;
            minKey = key;
        }
    }

    return result;
}

, , MinBy , . , , , , O (n log n), O (n).

+8

3 ( Field3), :

var earliest = booList.First(b => b.Field3 == booList.Min(e => e.Field3));

Enumerable.First Enumerable.Min

. O (n ^ 2) ( ), t24 . , O (n) ( ).

+5

OrderBy

var result = booList.OrderBy(p => p.field3).FirstOrDefault();
+3

O (n) . ( 3), :

var minDate = booList.Min(x=>x.field3);
var item = booList.First(x=>x.field3 == minDate);

.

+2

, BooClass , List<T>.Find. , :

void Main()
{
    List<BooClass> booList = new List<BooClass> { 
                        new BooClass { field3 = DateTime.MaxValue}, 
                        new BooClass { field3 = DateTime.Now },
                        new BooClass { field3 = DateTime.MinValue }};
    var pred = GetPredicate(booList);
    var result = booList.Find(pred);
}

public Predicate<BooClass> GetPredicate(List<BooClass> boos)
{
    var minDate = boos.Min(boo => boo.field3);   
    return bc => bc.field3 == minDate;
}

(which, like Said’s solution, also has O (n) time complexity), but I assume that would be considered a hoax ...

0
source

All Articles