Is there an enumerable extension method that repeats the enumerable indefinitely?
So for example, given an enumerable that returns: ["a", "b", "c"]. I would like a method that returns an infinite repeating sequence ["a", "b", "c", "a", "b", "c", "a", "b", "c" ... ]
This sounds a bit like Observable.Repeat, except I would like to operate on IEnumerables.
Enumerable.Repeat only generates an enumerable from a single element.
I don't know of anything built into LINQ, but it's really easy to create your own:
public static IEnumerable<T> RepeatIndefinitely<T>(this IEnumerable<T> source)
{
while (true)
{
foreach (var item in source)
{
yield return item;
}
}
}
Note that this evaluates source
multiple times - you might want to make it only do so once, creating a copy:
public static IEnumerable<T> RepeatIndefinitely<T>(this IEnumerable<T> source)
{
var list = source.ToList();
while (true)
{
foreach (var item in list)
{
yield return item;
}
}
}
Notes:
StringBuilder
references, for example, then any changes to the objects themselves will still be visible.Can't you use Repeat
+ SelectMany
?
var take100ABC = Enumerable.Repeat(new[] { "A", "B", "C" }, 100)
.SelectMany(col => col);
In my opinion an extension method is useful only if you need it often. I doubt that you need a RepeatIndefinitely
often. But a RepeatWhile
could be handy in many cases. You could it also for an infinite repetition.
So here is my my first attempt:
public static IEnumerable<TSource> RepeatWhile<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
{
TSource item = default(TSource);
do
{
foreach (TSource current in source)
{
item = current;
yield return item;
}
}
while (predicate(item));
yield break;
}
You can use it for your "infinite" repetion for example in this way:
string[] collection = { "A", "B", "C"};
var infiniteCollection = collection.RepeatWhile(s => s == s);
List<string> take1000OfInfinite = infiniteCollection.Take(1000).ToList();
Here is another option if you can use NuGet package of System.Interactive (aka Ix), just use Repeat()
.
var sequence = Enumerable.Range(1, 3).Repeat();
foreach (var item in sequence.Take(10))
{
Console.WriteLine(item); // 1, 2, 3, 1, 2, 3, 1, 2, 3, 1
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With