Skip to content

Instantly share code, notes, and snippets.

@badmotorfinger
Last active December 19, 2015 14:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save badmotorfinger/5972009 to your computer and use it in GitHub Desktop.
Save badmotorfinger/5972009 to your computer and use it in GitHub Desktop.
A LINQ extension method which eagerly finds an item or items with the lowest value in the collection.
[Test]
public void TestEmpty()
{
CollectionAssert.AreEqual(
new int[0].MinsBy(i => i),
new int[0]);
}
[Test]
public void TestPreserveOrderAndValue()
{
CollectionAssert.AreEqual(
new int[] {-3,-2,-1,0,1,2,3,4,5,-3}.MinsBy(i => i/2),
new int[] {-3, -2, -3});
}
[Test]
public void TestMinOfDefault()
{
var ints = new[] { 1, 2, 3, 4 };
var result = ints.MinsBy(i => i);
CollectionAssert.AreEqual(new[] { 1 }, result);
}
[Test]
public void TestMinOfDefaultCollection()
{
var ints = new[] { 2, 3, 4, -1, -1 };
var result = ints.MinsBy(i => i);
CollectionAssert.AreEqual(new[] { -1, -1 }, result);
}
/// <summary>
/// Finds an item in the collection with the lowest value. If two or more items have the same value, they are
/// also returned.
/// </summary>
/// <typeparam name="TItem">The source type.</typeparam>
/// <typeparam name="TCompare">The selected value for comparison.</typeparam>
/// <param name="collection">The source collection.</param>
/// <param name="selector">A selector.</param>
/// <returns>A collection of the items with the lowest compared value from the collection.</returns>
public static IReadOnlyList<TItem> MinsBy<TItem, TCompare>(this IEnumerable<TItem> collection, Func<TItem, TCompare> selector)
{
if (collection == null) throw new ArgumentNullException("collection");
if (selector == null) throw new ArgumentNullException("selector");
var minItems = new List<TItem>();
var minImage = default(TCompare);
var comparer = Comparer<TCompare>.Default;
foreach (var item in collection)
{
var image = selector(item);
var compareResult = minItems.Count == 0
? +1
: comparer.Compare(minImage, image);
if (compareResult > 0)
{
minImage = image;
minItems.Clear();
}
if (compareResult >= 0)
{
minItems.Add(item);
}
}
return minItems.AsReadOnly(); // Use Skip(0) for .NET < 4.5.
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment