dasmaze
dasmaze

Reputation: 652

Minimum of a struct-Array in C#

I used a Select() to perform a calculation on each member of an array of structs and now want to have the member for which a certain attribute is minimal. I wanted to use something like Min() on the selected sequence, but I don't know how to return the full struct, rather than only the attribute that is minmal.

Upvotes: 0

Views: 1202

Answers (3)

veggerby
veggerby

Reputation: 9020

How about ordering by your "value" and taking the first entry (the minimum value):

Persons.OrderBy(p => p.Age).FirstOrDefault();

That is of course if you only want one item (which is what you state).

Alternatively:

from p in Persons
where p.Age == Persons.Select(p1 => p1.Age).Min()
select p;

Will get you all items with minimum value.

Upvotes: 4

Jon Skeet
Jon Skeet

Reputation: 1500665

Sounds like you want to use MinBy from MoreLINQ:

public static TSource MinBy<TSource, TKey>(this IEnumerable<TSource> source,
    Func<TSource, TKey> selector, IComparer<TKey> comparer)
{
    source.ThrowIfNull("source");
    selector.ThrowIfNull("selector");
    comparer.ThrowIfNull("comparer");
    using (IEnumerator<TSource> sourceIterator = source.GetEnumerator())
    {
        if (!sourceIterator.MoveNext())
        {
            throw new InvalidOperationException("Sequence was empty");
        }
        TSource min = sourceIterator.Current;
        TKey minKey = selector(min);
        while (sourceIterator.MoveNext())
        {
            TSource candidate = sourceIterator.Current;
            TKey candidateProjected = selector(candidate);
            if (comparer.Compare(candidateProjected, minKey) < 0)
            {
                min = candidate;
                minKey = candidateProjected;
            }
        }
        return min;
    }
}

ThrowIfNull is defined as an extension method:

internal static void ThrowIfNull<T>(this T argument, string name)
    where T : class
{
    if (argument == null)
    {
        throw new ArgumentNullException(name);
    }
}

Upvotes: 3

Gad
Gad

Reputation: 42306

If i understand correctly, i'd say: use delegates...

Here's an Example from Craig Murphy

public class Person
{
          public int age;
          public string name;
          public Person(int age, string name)
          {
                   this.age = age;
                   this.name = name;
          }
}
// everyone under 25:
List<person> young = people.FindAll(delegate(Person p) { return p.age < 25; });

// sort your list: 
people.Sort(delegate(Person p1, Person p2)
   { return p1.age.CompareTo(p2.age); });

Upvotes: 0

Related Questions