Last active
January 15, 2016 21:40
-
-
Save miklund/17753ee7beaf167104f9 to your computer and use it in GitHub Desktop.
2011-01-13 Functional Patterns in C#: MapWhile
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Title: Functional Patterns in C#: MapWhile | |
# Author: Mikael Lundin | |
# Link: http://blog.mikaellundin.name/2011/01/13/functional-patterns-in-c-mapwhile.html |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
private const int AbundantSumMax = 28123; | |
public static void Main(string[] args) | |
{ | |
// Just create this once | |
var defaultRange = Enumerable.Range(1, AbundantSumMax); | |
// Returns true if n is abundant | |
Func<int, bool> isAbundant = n => Enumerable.Range(1, n / 2).Where(x => n % x == 0).Sum() > n; | |
// Get all abundants up to 28123 | |
var abundants = defaultRange.Where(isAbundant).ToList(); | |
// Get abundant sums | |
var abundantSums = GetAbundantSums(abundants); | |
// Invert abundant sums | |
var result = defaultRange.Except(abundantSums).Sum(); | |
Console.WriteLine("Result: {0}", result); | |
} | |
private static IEnumerable<int> GetAbundantSums(IList<int> abundants) | |
{ | |
// Unique set of numbers | |
var result = new HashSet<int>(); | |
// The Tortoise and the Hare | |
foreach (var abundant in abundants) | |
foreach (var abundantSum in abundants.MapWhile(x => x + abundant, x => x <= abundant)) | |
{ | |
result.Add(abundantSum); | |
} | |
return result; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public static class Extensions | |
{ | |
public static IEnumerable<T> MapWhile<T>(this IEnumerable<T> list, Func<T, T> mapFunction, Func<T, bool> whilePredicate) | |
{ | |
return MapWhile(list, (i, item) => mapFunction(item), (i, item) => whilePredicate(item)); | |
} | |
public static IEnumerable<T> MapWhile<T>(this IEnumerable<T> list, Func<int, T, T> mapFunction, Func<int, T, bool> whilePredicate) | |
{ | |
var enumerator = list.GetEnumerator(); | |
var index = 0; | |
while (enumerator.MoveNext()) | |
{ | |
if (!whilePredicate(index, enumerator.Current)) | |
{ | |
break; | |
} | |
yield return mapFunction(index, enumerator.Current); | |
index++; | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[TestFixture] | |
public class MapWhileShould | |
{ | |
[Test] | |
public void ReturnAtEndOfList() | |
{ | |
/* Setup */ | |
var list = new[] { 1, 2, 3, 4 }; | |
/* Test */ | |
var result = list.MapWhile(x => x * 2, x => true); | |
/* Assert */ | |
Assert.That(result.Sum(), Is.EqualTo(20)); | |
} | |
[Test] | |
public void BreakWhenWhileConditionIsFalse() | |
{ | |
/* Setup */ | |
var list = new[] { 1, 2, 3, 4 }; | |
/* Test */ | |
var result = list.MapWhile(x => x * 2, x => x < 3); | |
/* Assert */ | |
Assert.That(result.Sum(), Is.EqualTo(6)); | |
} | |
[Test] | |
public void ReturnEmptyListWhenWhileConditionIsFalseByDefault() | |
{ | |
/* Setup */ | |
var list = new[] { 1, 2, 3, 4 }; | |
/* Test */ | |
var result = list.MapWhile(x => x * 2, x => false); | |
/* Assert */ | |
Assert.That(result.Count(), Is.EqualTo(0)); | |
} | |
[Test] | |
public void WorkWithStrings() | |
{ | |
/* Setup */ | |
var list = new[] { "Hello", "World", "Santa", "Claudius" }; | |
/* Test */ | |
var result = list.MapWhile((i, s) => i % 2 == 0 ? s.ToUpper() : s, (i, s) => true); | |
/* Assert */ | |
Assert.That(string.Join(string.Empty, result), Is.EqualTo("HELLOWorldSANTAClaudius")); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment