Given a finite list of elements, how can I create a (lazily-evaluated, thanks LINQ!) infinite list that just keeps iterating over my initial list?
If the initial list is {1, 2, 3}
, I want the new list to return {1, 2, 3, 1, 2, 3, 1, ...}
Given a finite list of elements, how can I create a (lazily-evaluated, thanks LINQ!) infinite list that just keeps iterating over my initial list?
If the initial list is {1, 2, 3}
, I want the new list to return {1, 2, 3, 1, 2, 3, 1, ...}
yield return
is a fairly handy operator for this, although it doesn't really require LINQ specifically.
IEnumerable<int> GetInfiniteSeries(IEnumerable<int> items) {
while (true) {
foreach (var item in items) {
yield return item;
}
}
}
IEnumerable<T> Infinite(this IEnumerable<T> ienum)
{
List<T> list = ienum.ToList();
while (true)
foreach(var t in list)
yield return t;
}
foreach(int i in Enumerable.Range(1,3).Infinite())
Console.WriteLine(i);
ToList()
necessary? –
Jaunty ienum.Infinite().Infinite()
, when logically an Infinite()
implementation should support this. 2. If we neglect point 1, there is a performance issue: the enumerator keeps getting recreated and disposed. It would be much better it were rewitten as a for-loop that resets to 0
when it hits list.Count
. The other alternative is to rely on IEnumerator.Reset()
, but I suppose it is dangerous since so many implementations don't support it. –
Offstage Here's how I've done it eventually:
public static IEnumerable<T> AdNauseam<T>(this IEnumerable<T> i_list)
{
using(var etor = i_list.GetEnumerator())
{
while(true)
{
while(etor.MoveNext())
{
yield return etor.Current;
}
etor.Reset();
}
}
}
Usage:
var list = new[] {1, 2, 3}
var infinite = list.AdNauseam().Take(10);
The result:
{1, 2, 3, 1, 2, 3, 1, 2, 3, 1}
Another option, implement IEnumerator<T>
:
public class InfiniteEnumerator<T> : IEnumerator<T>
{
private IList<T> _items;
private int _index = -1;
public InfiniteEnumerator(IList<T> items)
{
if (items == null)
{
throw new ArgumentNullException("items");
}
_items = items;
}
public T Current
{
get { return _items[_index]; }
}
public void Dispose()
{
}
object System.Collections.IEnumerator.Current
{
get { return _items[_index]; }
}
public bool MoveNext()
{
if (_items.Count == 0)
{
return false;
}
_index = (_index + 1) % _items.Count;
return true;
}
public void Reset()
{
_index = -1;
}
}
ienum.Infinite().Infinite()
–
Paries © 2022 - 2024 — McMap. All rights reserved.