Skip to content

Instantly share code, notes, and snippets.

@miklund
Created January 11, 2016 20:38
Show Gist options
  • Save miklund/21b3c13421ed67a1c0b4 to your computer and use it in GitHub Desktop.
Save miklund/21b3c13421ed67a1c0b4 to your computer and use it in GitHub Desktop.
2012-06-23 Scan - 7 higher order functions
# Title: Scan - 7 higher order functions
# Author: Mikael Lundin
# Link: http://blog.mikaellundin.name/2012/06/23/scan-7-higher-order-functions.html
// Data
var initialBalance = 1122.73;
var transactions = new[] { -100.00, 450.34, -62.34, -127.00, -13.50, -12.92 };
// Scan transaction history
var accountHistory = transactions.Scan((balance, transaction) => balance + transaction, initialBalance);
// Print
Console.WriteLine("Initial balance:\n{0:c}", initialBalance);
Console.WriteLine("{0,15} {1,15}", "Transactions", "Balance");
foreach (var balance in transactions.Zip(accountHistory, Tuple.Create))
{
Console.WriteLine("{0,15:c} {1,15:c}", balance.Item1, balance.Item2);
}
// =>
// Initial balance:
// 1.122,73 kr
// Transactions Balance
// -100,00 kr 1.022,73 kr
// 450,34 kr 1.473,07 kr
// -62,34 kr 1.410,73 kr
// -127,00 kr 1.283,73 kr
// -13,50 kr 1.270,23 kr
// -12,92 kr 1.257,31 kr
// The bus departs at 20 minutes / 10 minutes intervals
// [20, 10, 20, 10, 20, ..]
var departures = 0.Expand(minute => minute == 20 ? 10 : 20);
// First bus departs at 10:09
var firstDeparture = DateTime.Parse("2012-06-23 10:09");
// Get timetable for each departure
var timetable = departures.Scan((time, minute) => time.AddMinutes(minute), firstDeparture);
Console.WriteLine("Bus departures at");
foreach (var departure in timetable.Take(10))
{
Console.WriteLine(departure.ToString("t"));
}
// Bus departures at
// 10:09
// 10:29
// 10:39
// 10:59
// 11:09
// 11:29
// 11:39
// 11:59
// 12:09
// 12:29
public static IEnumerable<U> Scan<T, U>(Func<U, T, U> fn, U state, IEnumerable<T> list)
{
if (list == null)
{
throw new ArgumentNullException("list", "Supplied list to Scan is not allowed to be null");
}
if (fn == null)
{
throw new ArgumentNullException("fn", "Supplied function to Scan is not allowed to be null");
}
var result = state;
foreach (var item in list)
{
yield return result = fn(result, item);
}
}
public static IEnumerable<U> Scan<T, U>(this IEnumerable<T> list, Func<U, T, U> fn, U state)
{
return Scan(fn, state, list);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment