Created
October 25, 2010 10:54
-
-
Save ldfallas/644768 to your computer and use it in GitHub Desktop.
This file contains 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
using System.Collections.Generic; | |
using System; | |
namespace Langexplr.Experiments | |
{ | |
public class MyTuple<T,K> | |
{ | |
public T Item1 { get; set; } | |
public K Item2 { get; set; } | |
public static MyTuple<T1,K1> Create<T1,K1>(T1 first, K1 second) | |
{ | |
return new MyTuple<T1,K1>() {Item1 = first, Item2 = second}; | |
} | |
} | |
public static class GroupByTests | |
{ | |
public static IEnumerable<MyTuple<T,IEnumerable<T>>> MyGroupBy<T>(this IEnumerable<T> en) | |
{ | |
return MyGroupBy(en,x => x); | |
} | |
public static IEnumerable<MyTuple<K,IEnumerable<T>>> MyGroupBy<T,K>(this IEnumerable<T> en,Func<T,K> keyExtraction) | |
{ | |
K currentGroupKey = default(K); | |
bool firstTime = true; | |
bool hasMoreElements = false; | |
bool yieldNewValue = false; | |
IEnumerator<T> enumerator = en.GetEnumerator(); | |
hasMoreElements = enumerator.MoveNext(); | |
while (hasMoreElements) | |
{ | |
if (firstTime) | |
{ | |
firstTime = false; | |
yieldNewValue = true; | |
currentGroupKey = keyExtraction(enumerator.Current); | |
} | |
else | |
{ | |
K lastKey; | |
while((lastKey = keyExtraction(enumerator.Current)).Equals( currentGroupKey) && | |
(hasMoreElements = enumerator.MoveNext())) | |
{ | |
} | |
if(hasMoreElements && | |
!lastKey.Equals(currentGroupKey)) | |
{ | |
currentGroupKey = lastKey; | |
yieldNewValue = true; | |
} | |
else | |
{ | |
yieldNewValue = false; | |
} | |
} | |
if (yieldNewValue) { | |
yield return MyTuple<K,IEnumerable<T>>.Create( | |
currentGroupKey, | |
ReturnSubSequence((x) => { | |
hasMoreElements = enumerator.MoveNext(); | |
return hasMoreElements && | |
x.Equals(keyExtraction(enumerator.Current)); },enumerator, | |
currentGroupKey, | |
enumerator.Current)); | |
} | |
} | |
} | |
static IEnumerable<T> ReturnSubSequence<T,K>(Predicate<K> pred, IEnumerator<T> seq,K currentElement,T first) | |
{ | |
yield return first; | |
while( pred(currentElement)) | |
{ | |
yield return seq.Current; | |
} | |
} | |
public static IEnumerable<MyTuple<T,IList<T>>> MyGroupByWithLists<T>(this IEnumerable<T> enumerable) | |
{ | |
return MyGroupByWithLists(enumerable, x => x); | |
} | |
public static IEnumerable<MyTuple<K,IList<T>>> MyGroupByWithLists<T,K>(this IEnumerable<T> en,Func<T,K> keyExtraction) | |
{ | |
K currentKey = default(K); | |
bool firstTime = true; | |
IList<T> currentGroup = new List<T>(); | |
foreach(var aValue in en) | |
{ | |
if (firstTime) | |
{ | |
currentKey = keyExtraction(aValue); | |
firstTime = false; | |
} | |
else | |
{ | |
K tmpKey = keyExtraction(aValue); | |
if (!tmpKey.Equals(currentKey)) | |
{ | |
yield return MyTuple<K,IList<T>>.Create(currentKey, currentGroup); | |
currentGroup = new List<T>(); | |
currentKey = tmpKey; | |
} | |
} | |
currentGroup.Add(aValue); | |
} | |
if (currentGroup.Count > 0) | |
{ | |
yield return MyTuple<K,IList<T>>.Create(currentKey, currentGroup); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment