Skip to content

Instantly share code, notes, and snippets.

@yreynhout
Created February 11, 2015 16:47
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 yreynhout/f2165508d84266c2c416 to your computer and use it in GitHub Desktop.
Save yreynhout/f2165508d84266c2c416 to your computer and use it in GitHub Desktop.
Order them sources
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
namespace IAmScaredOfMonstersInTheDark
{
class Program
{
static void Main()
{
var source1 = new[] {new Record(1), new Record(3), new Record(4), new Record(6), new Record(10)};
var source2 = new[] {new Record(2), new Record(3), new Record(5), new Record(7), new Record(8)};
var source3 = new Record[0];
var source4 = new[] {new Record(0)};
foreach (var record in new CompositeTimestampedEnumerable<Record>(new IEnumerable<Record>[]
{
source1,
source2,
source3,
source4
}))
{
Console.WriteLine(record.Ticks);
}
Console.ReadLine();
}
}
interface ITimestamped
{
long Ticks { get; }
}
class Record : ITimestamped
{
public Record(long ticks)
{
Ticks = ticks;
}
public long Ticks { get; private set; }
}
class CompositeTimestampedEnumerable<T> : IEnumerable<T> where T : ITimestamped
{
private readonly IEnumerable<T>[] _enumerables;
public CompositeTimestampedEnumerable(IEnumerable<T>[] enumerables)
{
if (enumerables == null) throw new ArgumentNullException("enumerables");
_enumerables = enumerables;
}
public IEnumerator<T> GetEnumerator()
{
return new CompositeTimestampedEnumerator<T>(
Array.ConvertAll(_enumerables, enumerable => enumerable.GetEnumerator()));
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
class CompositeTimestampedEnumerator<TResult> : IEnumerator<TResult> where TResult : ITimestamped
{
private readonly IEnumerator<TResult>[] _enumerators;
private readonly bool[] _moved;
private IEnumerator<TResult> _current;
public CompositeTimestampedEnumerator(IEnumerator<TResult>[] enumerators)
{
if (enumerators == null) throw new ArgumentNullException("enumerators");
_enumerators = enumerators;
_moved = new bool[enumerators.Length];
}
public bool MoveNext()
{
if (_current == null)
{
for (var index = 0; index < _enumerators.Length; index++)
{
_moved[index] = _enumerators[index].MoveNext();
}
}
else
{
var index = Array.IndexOf(_enumerators, _current);
_moved[index] = _current.MoveNext();
}
_current = _enumerators.
Where((enumerator, index) => _moved[index]).
OrderBy(enumerator => enumerator.Current.Ticks).
FirstOrDefault();
return _current != null;
}
public void Reset()
{
for (var index = 0; index < _enumerators.Length; index++)
{
_enumerators[index].Reset();
_moved[index] = false;
}
_current = null;
}
public TResult Current
{
get { return _current.Current; }
}
object IEnumerator.Current
{
get { return Current; }
}
public void Dispose()
{
for (var index = 0; index < _enumerators.Length; index++)
{
_enumerators[index].Dispose();
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment