查找最大/最小元素,而无需使用IComparable的< T>最小、元素、最大、GT

2023-09-03 05:16:11 作者:○萌系少年

说我有以下几点:

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

public List<BooClass> booList;

因此​​,例如如何使用我得到FIELD3最早的时间因素booList.Find()

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

编辑道歉,我的意思是公开的例子简单各个领域。我知道能在LINQ做到这一点,我想知道如果有一个简单的单行条件查找方法。

Edit Apologies, I meant to make all the fields public for simplicity of the example. I know can do it in linq, I wondered if there is a simple single line condition for the Find method.

推荐答案

F#有方便的 minBy maxBy 运营商,我想实现的C#扩展方法,因为LINQ的库忽略它们。这是一个有点工作,但只有一点点,它可以让你避免复杂的EX pressions如

F# has handy minBy and maxBy operators, which I like to implement as C# extension methods, since the Linq library omits them. It's a bit of work, but only a bit, and it allows you to avoid complex expressions such as

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

相反,你可以输入:

Instead, you can type this:

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

一个简单的实现:

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

此也稍微大于复合前pression在顶部更有效,因为MinBy迭代序列只出现一次,而前pression迭代一次以上且小于或等于两次。当然,排序,然后采取的第一项要求排序,这是O(n log n)的,而这仅仅是为O(n)。

This is also somewhat more efficient than the complex expression at the top, since MinBy iterates the sequence exactly once, while the expression iterates more than once and less than or equal to twice. And, of course, sorting and then taking the first item requires sorting, which is O(n log n), while this is just O(n).