#region License and Terms
// MoreLINQ - Extensions to LINQ to Objects
// Copyright (c) 2008-2011 Jonathan Skeet. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#endregion
using System;
using System.Collections.Generic;
namespace MoreLinq
{
public static partial class MoreEnumerable
{
///
/// Returns the minimal element of the given sequence, based on
/// the given projection.
///
///
/// If more than one element has the minimal projected value, the first
/// one encountered will be returned. This overload uses the default comparer
/// for the projected type. This operator uses immediate execution, but
/// only buffers a single result (the current minimal element).
///
/// Type of the source sequence
/// Type of the projected element
/// Source sequence
/// Selector to use to pick the results to compare
/// The minimal element, according to the projection.
/// or is null
/// is empty
public static TSource MinBy(this IEnumerable source,
Func selector)
{
return source.MinBy(selector, Comparer.Default);
}
///
/// Returns the minimal element of the given sequence, based on
/// the given projection and the specified comparer for projected values.
///
///
/// If more than one element has the minimal projected value, the first
/// one encountered will be returned. This overload uses the default comparer
/// for the projected type. This operator uses immediate execution, but
/// only buffers a single result (the current minimal element).
///
/// Type of the source sequence
/// Type of the projected element
/// Source sequence
/// Selector to use to pick the results to compare
/// Comparer to use to compare projected values
/// The minimal element, according to the projection.
/// ,
/// or is null
/// is empty
public static TSource MinBy(this IEnumerable source,
Func selector, IComparer comparer)
{
source.ThrowIfNull("source");
selector.ThrowIfNull("selector");
comparer.ThrowIfNull("comparer");
using (IEnumerator 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;
}
}
}
}