Skip to content

Commit

Permalink
Replace WithMin/WithMax methods with MinBy/MaxBy and associated overl…
Browse files Browse the repository at this point in the history
…oads
  • Loading branch information
Majiir committed Sep 2, 2014
1 parent f0e05b8 commit 381b369
Show file tree
Hide file tree
Showing 6 changed files with 174 additions and 66 deletions.
64 changes: 0 additions & 64 deletions Plugin/EnumerableExtensions/EnumerableExtensions.cs
Expand Up @@ -35,70 +35,6 @@ public static IEnumerable<Pair<T>> AdjacentPairs<T>(this IEnumerable<T> sequence
yield return new Pair<T>(previous, first);
}

public static T WithMax<T>(this IEnumerable<T> sequence, Func<T, float> selector)
{
T best = default(T);
var bestValue = float.NegativeInfinity;
foreach (var element in sequence)
{
var value = selector(element);
if (value > bestValue)
{
best = element;
bestValue = value;
}
}
return best;
}

public static T WithMin<T>(this IEnumerable<T> sequence, Func<T, float> selector)
{
T best = default(T);
var bestValue = float.PositiveInfinity;
foreach (var element in sequence)
{
var value = selector(element);
if (value < bestValue)
{
best = element;
bestValue = value;
}
}
return best;
}

public static T WithMax<T>(this IEnumerable<T> sequence, Func<T, double> selector)
{
T best = default(T);
var bestValue = double.NegativeInfinity;
foreach (var element in sequence)
{
var value = selector(element);
if (value > bestValue)
{
best = element;
bestValue = value;
}
}
return best;
}

public static T WithMin<T>(this IEnumerable<T> sequence, Func<T, double> selector)
{
T best = default(T);
var bestValue = double.PositiveInfinity;
foreach (var element in sequence)
{
var value = selector(element);
if (value < bestValue)
{
best = element;
bestValue = value;
}
}
return best;
}

public static IEnumerable<T> Append<T>(this IEnumerable<T> sequence, T element)
{
return new AppendIterator<T>(sequence, element);
Expand Down
148 changes: 148 additions & 0 deletions Plugin/EnumerableExtensions/MinMaxBy.cs
@@ -0,0 +1,148 @@
using System;
using System.Collections.Generic;

namespace Kethane.EnumerableExtensions
{
public static class MinMaxBy
{
public static T MinBy<T, TKey>(this IEnumerable<T> sequence, Func<T, TKey> selector)
{
TKey key;
return MinBy(sequence, selector, out key);
}

public static T MaxBy<T, TKey>(this IEnumerable<T> sequence, Func<T, TKey> selector)
{
TKey key;
return MaxBy(sequence, selector, out key);
}

public static T MinBy<T, TKey>(this IEnumerable<T> sequence, Func<T, TKey> selector, IComparer<TKey> comparer)
{
TKey key;
return MinBy(sequence, selector, out key, comparer);
}

public static T MaxBy<T, TKey>(this IEnumerable<T> sequence, Func<T, TKey> selector, IComparer<TKey> comparer)
{
TKey key;
return MaxBy(sequence, selector, out key, comparer);
}

public static T MinBy<T, TKey>(this IEnumerable<T> sequence, Func<T, TKey> selector, out TKey minKey)
{
return minByImpl(sequence, selector, out minKey, Comparer<TKey>.Default);
}

public static T MaxBy<T, TKey>(this IEnumerable<T> sequence, Func<T, TKey> selector, out TKey maxKey)
{
return minByImpl(sequence, selector, out maxKey, new ReverseComparer<TKey>(Comparer<TKey>.Default));
}

public static T MinBy<T, TKey>(this IEnumerable<T> sequence, Func<T, TKey> selector, out TKey minKey, IComparer<TKey> comparer)
{
if (comparer == null) { throw new ArgumentNullException("comparer"); }
return minByImpl(sequence, selector, out minKey, comparer);
}

public static T MaxBy<T, TKey>(this IEnumerable<T> sequence, Func<T, TKey> selector, out TKey maxKey, IComparer<TKey> comparer)
{
if (comparer == null) { throw new ArgumentNullException("comparer"); }
return minByImpl(sequence, selector, out maxKey, new ReverseComparer<TKey>(comparer));
}

public static T MinByOrDefault<T, TKey>(this IEnumerable<T> sequence, Func<T, TKey> selector)
{
TKey key;
return MinByOrDefault(sequence, selector, out key);
}

public static T MaxByOrDefault<T, TKey>(this IEnumerable<T> sequence, Func<T, TKey> selector)
{
TKey key;
return MaxByOrDefault(sequence, selector, out key);
}

public static T MinByOrDefault<T, TKey>(this IEnumerable<T> sequence, Func<T, TKey> selector, IComparer<TKey> comparer)
{
TKey key;
return MinByOrDefault(sequence, selector, out key, comparer);
}

public static T MaxByOrDefault<T, TKey>(this IEnumerable<T> sequence, Func<T, TKey> selector, IComparer<TKey> comparer)
{
TKey key;
return MaxByOrDefault(sequence, selector, out key, comparer);
}

public static T MinByOrDefault<T, TKey>(this IEnumerable<T> sequence, Func<T, TKey> selector, out TKey minKey)
{
return minByOrDefaultImpl(sequence, selector, out minKey, Comparer<TKey>.Default);
}

public static T MaxByOrDefault<T, TKey>(this IEnumerable<T> sequence, Func<T, TKey> selector, out TKey maxKey)
{
return minByOrDefaultImpl(sequence, selector, out maxKey, new ReverseComparer<TKey>(Comparer<TKey>.Default));
}

public static T MinByOrDefault<T, TKey>(this IEnumerable<T> sequence, Func<T, TKey> selector, out TKey minKey, IComparer<TKey> comparer)
{
if (comparer == null) { throw new ArgumentNullException("comparer"); }
return minByOrDefaultImpl(sequence, selector, out minKey, comparer);
}

public static T MaxByOrDefault<T, TKey>(this IEnumerable<T> sequence, Func<T, TKey> selector, out TKey maxKey, IComparer<TKey> comparer)
{
if (comparer == null) { throw new ArgumentNullException("comparer"); }
return minByOrDefaultImpl(sequence, selector, out maxKey, new ReverseComparer<TKey>(comparer));
}

private static T minByImpl<T, TKey>(IEnumerable<T> sequence, Func<T, TKey> selector, out TKey key, IComparer<TKey> comparer)
{
return minByOrEmpty(sequence, selector, out key, comparer, throwOnEmpty<T>);
}

private static T minByOrDefaultImpl<T, TKey>(IEnumerable<T> sequence, Func<T, TKey> selector, out TKey key, IComparer<TKey> comparer)
{
return minByOrEmpty(sequence, selector, out key, comparer, () => default(T));
}

private static T throwOnEmpty<T>()
{
throw new InvalidOperationException("Sequence is empty");
}

private static T minByOrEmpty<T, TKey>(IEnumerable<T> sequence, Func<T, TKey> selector, out TKey key, IComparer<TKey> comparer, Func<T> emptyHandler)
{
if (sequence == null) { throw new ArgumentNullException("sequence"); }
if (selector == null) { throw new ArgumentNullException("selector"); }

using (var enumerator = sequence.GetEnumerator())
{
if (!enumerator.MoveNext())
{
T value = emptyHandler();
key = selector(value);
return value;
}

T min = enumerator.Current;
TKey minKey = selector(min);

while (enumerator.MoveNext())
{
T current = enumerator.Current;
TKey currentKey = selector(current);
if (comparer.Compare(currentKey, minKey) < 0)
{
min = current;
minKey = currentKey;
}
}

key = minKey;
return min;
}
}
}
}
22 changes: 22 additions & 0 deletions Plugin/EnumerableExtensions/ReverseComparer.cs
@@ -0,0 +1,22 @@
using System.Collections.Generic;

namespace Kethane.EnumerableExtensions
{
internal class ReverseComparer<T> : IComparer<T>
{
private readonly IComparer<T> comparer;

public ReverseComparer(IComparer<T> comparer)
{
this.comparer = comparer;
}

public int Compare(T x, T y)
{
int comparison = comparer.Compare(x, y);
if (comparison < 0) { return 1; }
else if (comparison > 0) { return -1; }
else { return 0; }
}
}
}
2 changes: 1 addition & 1 deletion Plugin/GeodesicGrid/Cell.cs
Expand Up @@ -181,7 +181,7 @@ public bool Contains(Vector3 line, int level)

private Cell searchNeighbors(Vector3 line, int level)
{
return this.GetNeighbors(level).Prepend(this).WithMax(c => Vector3.Dot(c.Position, line));
return this.GetNeighbors(level).Prepend(this).MaxBy(c => Vector3.Dot(c.Position, line));
}

#endregion
Expand Down
2 changes: 1 addition & 1 deletion Plugin/GeodesicGrid/Triangle.cs
Expand Up @@ -127,7 +127,7 @@ public IEnumerable<Cell> GetVertices(int level)
}
}

return candidates.Select(t => t.Raycast(ray, level, heightAt)).Where(h => h.HasValue).WithMin(t => t.Value.Distance);
return candidates.Select(t => t.Raycast(ray, level, heightAt)).Where(h => h.HasValue).MinByOrDefault(t => t.Value.Distance);
}

public TriangleHit? Raycast(Ray ray, int level, Func<Cell, float> heightAt)
Expand Down
2 changes: 2 additions & 0 deletions Plugin/Kethane.csproj
Expand Up @@ -46,6 +46,8 @@
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="EnumerableExtensions\MinMaxBy.cs" />
<Compile Include="EnumerableExtensions\ReverseComparer.cs" />
<Compile Include="GeodesicGrid\BoundsMap.cs" />
<Compile Include="GeodesicGrid\Cell.cs" />
<Compile Include="CellularResourceGenerator.cs" />
Expand Down

0 comments on commit 381b369

Please sign in to comment.