Skip to content

Instantly share code, notes, and snippets.

@beyond-code-github
Last active January 4, 2016 01:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save beyond-code-github/8549366 to your computer and use it in GitHub Desktop.
Save beyond-code-github/8549366 to your computer and use it in GitHub Desktop.
Efficient Iterator sample
public class EfficientIterator<TOne, TTwo>
{
private Action<TOne, TTwo> always = (one, two) => { };
private Action<TOne, TTwo> match = (one, two) => { };
private Action<TOne> oneOnly = (one) => { };
private Action<TTwo> twoOnly = (two) => { };
private readonly Func<TOne, TTwo, int> compare;
public Action<TOne, TTwo> Always { set { this.always = value; } }
public Action<TOne, TTwo> Match { set { this.match = value; } }
public Action<TOne> OneOnly { set { this.oneOnly = value; } }
public Action<TTwo> TwoOnly { set { this.twoOnly = value; } }
public EfficientIterator(Func<TOne, TTwo, int> compare)
{
this.compare = compare;
}
public void RunToEnd(IEnumerable<TOne> listOne, IEnumerable<TTwo> listTwo)
{
using (var listOneEnumerator = listOne.GetEnumerator())
using (var listTwoEnumerator = listTwo.GetEnumerator())
{
var listOneIterating = listOneEnumerator.MoveNext();
var listTwoIterating = listTwoEnumerator.MoveNext();
while (listOneIterating || listTwoIterating)
{
int result = 0;
if (listOneIterating && listTwoIterating)
{
result = this.compare(listOneEnumerator.Current, listTwoEnumerator.Current);
// a and b are equal
if (result == 0)
{
this.always(listOneEnumerator.Current, listTwoEnumerator.Current);
this.match(listOneEnumerator.Current, listTwoEnumerator.Current);
listOneIterating = listOneEnumerator.MoveNext();
listTwoIterating = listTwoEnumerator.MoveNext();
continue;
}
}
// list one has run out, or it's current item is greater than list two
if (!listOneIterating || result > 0)
{
this.always(default(TOne), listTwoEnumerator.Current);
this.twoOnly(listTwoEnumerator.Current);
listTwoIterating = listTwoEnumerator.MoveNext();
continue;
}
// list two has run out, or it's current item is greater than list one
if (!listTwoIterating || result < 0)
{
this.always(listOneEnumerator.Current, default(TTwo));
this.oneOnly(listOneEnumerator.Current);
listOneIterating = listOneEnumerator.MoveNext();
continue;
}
}
}
}
}
@beyond-code-github
Copy link
Author

Awesome thanks! I'd just come on to make the change in the second point and seen that you've beaten me to it. Good job :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment