Skip to content

Instantly share code, notes, and snippets.

@ldiego08
Created March 20, 2013 21:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ldiego08/5208654 to your computer and use it in GitHub Desktop.
Save ldiego08/5208654 to your computer and use it in GitHub Desktop.
Sample implementation of some LINQ methods.
using System;
using System.Collections.Generic;
namespace Codenough.Demos.MapReduce
{
public static class ListQuery
{
public delegate bool Comparator<TSource>(TSource current, TSource target);
public delegate TAccumulate Aggregator<TSource, TAccumulate>(TSource current, TAccumulate value);
public static IEnumerable<TResult> Select<TSource, TResult>(IEnumerable<TSource> source, Func<TSource, TResult> selector)
{
if (source == null)
{
throw new ArgumentNullException("source");
}
if (selector == null)
{
throw new ArgumentNullException("selector");
}
using (var iterator = source.GetEnumerator())
{
if (!iterator.MoveNext())
{
throw new InvalidOperationException("Source enumerator contains no elements.");
}
do
{
var currentElement = iterator.Current;
yield return selector(currentElement);
} while (iterator.MoveNext());
}
}
public static IEnumerable<TSource> Where<TSource>(IEnumerable<TSource> source, Predicate<TSource> predicate)
{
if (source == null)
{
throw new ArgumentNullException("source");
}
if (predicate == null)
{
throw new ArgumentNullException("predicate");
}
using (var iterator = source.GetEnumerator())
{
if (!iterator.MoveNext())
{
throw new InvalidOperationException("Source enumerator contains no elements.");
}
do
{
var currentElement = iterator.Current;
if (predicate(currentElement))
{
yield return currentElement;
}
} while (iterator.MoveNext());
}
}
public static TSource Where<TSource>(IEnumerable<TSource> source, Comparator<TSource> comparator)
{
if (source == null)
{
throw new ArgumentNullException("source");
}
if (comparator == null)
{
throw new ArgumentNullException("comparator");
}
using (var iterator = source.GetEnumerator())
{
if (!iterator.MoveNext())
{
throw new InvalidOperationException("Source enumerator contains no elements.");
}
var resultElement = iterator.Current;
do
{
var currentElement = iterator.Current;
if (comparator(currentElement, resultElement))
{
resultElement = currentElement;
}
} while (iterator.MoveNext());
return resultElement;
}
}
public static TAccumulate Aggregate<TSource, TAccumulate>(IEnumerable<TSource> source, TAccumulate seed, Aggregator<TSource, TAccumulate> aggregator)
{
return Aggregate(source, seed, x => x, aggregator);
}
public static TResult Aggregate<TSource, TAccumulate, TResult>(IEnumerable<TSource> source, TAccumulate seed, Func<TAccumulate, TResult> selector, Aggregator<TSource, TAccumulate> aggregator)
{
if (source == null)
{
throw new ArgumentNullException("source");
}
if (aggregator == null)
{
throw new ArgumentNullException("aggregator");
}
if (selector == null)
{
throw new ArgumentNullException("selector");
}
using (var iterator = source.GetEnumerator())
{
if (!iterator.MoveNext())
{
throw new InvalidOperationException("Source enumerator contains no elements.");
}
TAccumulate accumulate = seed;
do
{
var currentElement = iterator.Current;
accumulate = aggregator(currentElement, accumulate);
} while (iterator.MoveNext());
return selector(accumulate);
}
}
public static IEnumerable<TSource> Order<TSource, TKey>(IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
where TKey : IComparable<TKey>
{
if (source == null)
{
throw new ArgumentNullException("source");
}
if (keySelector == null)
{
throw new ArgumentNullException("keySelector");
}
var sourceList = new List<TSource>(source);
if (sourceList.Count == 0)
{
throw new InvalidOperationException("Source sequence is empty.");
}
for (int iterator = 0; iterator < sourceList.Count; iterator++)
{
for (int index = 0; index < sourceList.Count - 1; index++)
{
var currentItem = sourceList[index];
var currentValue = keySelector(currentItem);
var nextItem = sourceList[index + 1];
var nextValue = keySelector(nextItem);
if (currentValue.CompareTo(nextValue) > 0)
{
sourceList.Remove(nextItem);
sourceList.Insert(index, nextItem);
}
}
}
return sourceList;
}
public static IDictionary<TKey, IList<TSource>> Group<TKey, TSource>(IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
{
if (source == null)
{
throw new ArgumentNullException("source");
}
if (keySelector == null)
{
throw new ArgumentNullException("keySelector");
}
using (var iterator = source.GetEnumerator())
{
if (!iterator.MoveNext())
{
throw new InvalidOperationException("Source enumerator contains no elements.");
}
var groups = new Dictionary<TKey, IList<TSource>>();
do
{
var currentElement = iterator.Current;
var key = keySelector(currentElement);
if (groups.ContainsKey(key))
{
groups[key].Add(currentElement);
}
else
{
groups.Add(key, new List<TSource>() { currentElement });
}
} while (iterator.MoveNext());
return groups;
}
}
}
}
using Codenough.Demos.MapReduce.Data;
using Codenough.Demos.MapReduce.Data.Model;
using System;
using System.Linq;
namespace Codenough.Demos.MapReduce
{
class Program
{
static void Main(string[] args)
{
var dataSource = new DataSource();
// Ex. 1: Print all car brands.
var carBrands = ListQuery
.Aggregate(dataSource.Cars, String.Empty, JoinCarBrand)
.Remove(0, 2);
Console.WriteLine("Car brands:" + carBrands);
Console.WriteLine();
// Ex. 2: Select all Toyota sales.
var toyotaSales = ListQuery.Where(dataSource.Sales, sale => sale.Car.Brand == "Toyota");
Console.WriteLine("Total Toyota sales: " + toyotaSales.Count());
Console.WriteLine();
// Ex. 3: Find buys of youngest person.
var youngerPerson = ListQuery.Where(dataSource.Persons, (cur, target) => cur.Age < target.Age);
var youngerPersonBuys = ListQuery.Where(dataSource.Sales, sale => sale.Buyer == youngerPerson);
Console.WriteLine(String.Format("The younger person is {0} {1} with a total of {2} cars bought.", youngerPerson.FirstName, youngerPerson.LastName, youngerPersonBuys.Count()));
Console.WriteLine();
// Ex. 4: Find most expensive sale.
var mostExpensiveSale = ListQuery.Where(dataSource.Sales, (cur, target) => cur.Cost > target.Cost);
Console.WriteLine(String.Format("Most expensive sale was for {0:c}", mostExpensiveSale.Cost));
Console.WriteLine();
// Ex. 5: Sum sale costs where both buyer and seller are male.
var maleSales = ListQuery.Where(dataSource.Sales, sale => sale.Seller.Gender == "Male" && sale.Buyer.Gender == "Male");
var maleSalesCost = ListQuery.Aggregate(maleSales, 0.0, (sale, total) => total + sale.Cost);
Console.WriteLine(String.Format("Total cost of sales where both buyer and seller are male: {0:c}", maleSalesCost));
Console.WriteLine();
// Ex. 6: Find age of the youngest person that has bought more than $40,000.
var youngerPersonWithHighestSale = ListQuery.Where(dataSource.Sales, (cur, target) => cur.Cost > 40000 && cur.Buyer.Age < target.Buyer.Age);
Console.WriteLine(String.Format("Youngest person with a buy for more than $40,000: {0} {1}", youngerPersonWithHighestSale.Buyer.FirstName, youngerPersonWithHighestSale.Buyer.LastName));
Console.WriteLine();
// Ex. 7: Sort sales by cost.
var sortedSalesByCost = ListQuery.Order(dataSource.Sales, sale => sale.Cost);
Console.WriteLine("Sales sorted by cost:");
foreach (var sale in sortedSalesByCost)
{
Console.WriteLine(String.Format("\t{0} = {1:c}", sale.Car.Brand, sale.Cost));
}
Console.WriteLine();
// Ex. 8: Select cars original costs.
var carCosts = ListQuery.Select(dataSource.Cars, car => car.OriginalValue);
Console.WriteLine("Original car costs:");
foreach (var carCost in carCosts)
{
Console.WriteLine("\t" + carCost);
}
Console.WriteLine();
// Ex. 9: Index cars by brand.
var salesGroupedByCarBrand = ListQuery.Group(dataSource.Sales, sale => sale.Car.Brand);
Console.WriteLine("Cars grouped by brand:");
foreach (var saleGroup in salesGroupedByCarBrand)
{
Console.WriteLine(String.Format("\t{0} = {1}", saleGroup.Key, saleGroup.Value.Count));
}
Console.WriteLine();
// Ex. 10: Group sales by buyers and sellers.
var salesGroupedByBuyerAndSeller = ListQuery.Group(dataSource.Sales, sale => new { sale.Buyer, sale.Seller });
Console.WriteLine("Sales grouped by buyer and seller:");
foreach (var saleGroup in salesGroupedByBuyerAndSeller)
{
Console.WriteLine(String.Format("\t{0}/{1} = {2}", saleGroup.Key.Buyer.FirstName, saleGroup.Key.Seller.FirstName, saleGroup.Value.Count));
}
Console.WriteLine();
// Ex. 11: Find most sold car.
var salesGroupedByCar = ListQuery.Group(dataSource.Sales, sale => sale.Car);
var mostSoldCar = ListQuery.Where(salesGroupedByCar, (cur, target) => cur.Value.Count > target.Value.Count).Key;
Console.WriteLine(String.Format("Most sold car brand: {0}", mostSoldCar.Brand));
Console.ReadLine();
}
static string JoinCarBrand(Car car, string aggregate)
{
return String.Format("{0}, {1}", aggregate, car.Brand);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment