tags:

views:

2151

answers:

4

I'd like something like

int minIndex = list.FindMin(delegate (MyClass a, MyClass b) {returns a.CompareTo(b);});

Is there a builtin way to do this in .NET?

+6  A: 

Try looking at these:

Min

Max

As long as your class implements IComparable, all you have to do is:

List<MyClass> list = new List();
//add whatever you need to add

MyClass min = list.Min();
MyClass max = list.Max();
Nicholas Mancuso
.NET 3.5 I guess. I'm still in 2, didn't even realize these existed.
ripper234
If you're still in .NET 2.0, how can this be your accepted answer?
Kyralessa
Because it's a good one (I should just move to 3.5 :)
ripper234
+2  A: 

Using Linq you have the Min() and Max() functions.

So you can do list.AsQueryable().Min();

Rune Grimstad
Minor: no need for AsQueryable() here...
Marc Gravell
I wasn't aware that the List<> had Min and Max functions. You learn something new every day here! :-)
Rune Grimstad
+1  A: 

You note that "I'm still in 2" - you might, then, want to look at LINQBridge. This is actually aimed at C# 3.0 and .NET 2.0, but you should be able to use it with C# 2.0 and .NET 2.0 - just you'll have to use the long-hand:

MyClass min = Enumerable.Min(list),
        max = Enumerable.Max(list);

Of course, it will be easier if you can switch to C# 3.0 (still targetting .NET 2.0).

And if LINQBridge isn't an option, you can implement it yourself:

static void Main()
{
    int[] data = { 3, 5, 1, 5, 5 };
    int min = Min(data);
}
static T Min<T>(IEnumerable<T> values)
{
    return Min<T>(values, Comparer<T>.Default);
}
static T Min<T>(IEnumerable<T> values, IComparer<T> comparer)
{
    bool first = true;
    T result = default(T);
    foreach(T value in values) {
        if(first)
        {
            result = value;
            first = false;
        }
        else
        {
            if(comparer.Compare(result, value) > 0) 
            {
                result = value;
            }
        }
    }
    return result;
}
Marc Gravell
I ended up implementing it - I believe my code is EXACTLY like your snippet. Did you take it from my source control? :)
ripper234
+2  A: 

Well, if you can't use .NET 3.5, you could always sort the list and then return list[0]. It might not be the fastest way, but it's probably the shortest code, especially if your class already implements IComparable.

List<SomeClass> list = new List<SomeClass>();
// populate the list
// assume that SomeClass implements IComparable
list.Sort();
return list[0];               // min, or
return list[list.Count - 1];  // max

This also assumes, of course, that it doesn't matter which item you return if you have multiple items that are the minimum or maximum.

If your class doesn't implement IComparable, you can pass in an anonymous delegate, something like this:

list.Sort(delegate(SomeClass x, SomeClass y) { return string.Compare(x.Name, y.Name); });
Kyralessa
I remain baffled as to why this got downvoted.
Kyralessa
i agree, i like it...especially given the fact he is in 2.0. Upvoted!
Ken