无限重复一次可枚举

Dav*_*ier 10 c# linq

是否有可枚举的扩展方法无限期地重复可枚举?

因此,例如,给定一个可返回的枚举:["a","b","c"].我想要一个返回无限重复序列的方法["a","b","c","a","b","c","a","b","c"...... ]

这听起来有点像Observable.Repeat,除了我想在IEnumerables上操作.

Enumerable.Repeat仅从单个元素生成可枚举.

Jon*_*eet 20

我不知道LINQ中内置的任何内容,但创建自己的内容非常简单:

public static IEnumerable<T> RepeatIndefinitely<T>(this IEnumerable<T> source)
{
    while (true)
    {
        foreach (var item in source)
        {
            yield return item;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,这source多次评估- 您可能只想这样做一次,创建一个副本:

public static IEnumerable<T> RepeatIndefinitely<T>(this IEnumerable<T> source)
{
    var list = source.ToList();
    while (true)
    {
        foreach (var item in list)
        {
            yield return item;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

笔记:

  • 创建序列的副本意味着可以自由地修改原始序列,而不必担心此代码同时迭代它.
  • 当然,创建序列的副本意味着它需要足够小以适应内存.这可能不太理想.
  • 这只会在您开始迭代结果时创建一个副本.这很容易令人惊讶.另一种方法是使用非迭代器方法创建副本,然后委托给私有迭代器方法.这是LINQ中用于参数验证的方法.
  • 副本很浅 - StringBuilder例如,如果源是一系列引用,那么对象本身的任何更改仍然可见.


Tim*_*ter 6

你不能用Repeat+ SelectMany

var take100ABC = Enumerable.Repeat(new[] { "A", "B", "C" }, 100)
                           .SelectMany(col => col);
Run Code Online (Sandbox Code Playgroud)

在我看来,扩展方法只有在经常需要时才有用.我怀疑你RepeatIndefinitely经常需要一个.但RepeatWhile在许多情况下,a 可能很方便.你也可以无限重复.

所以这是我的第一次尝试:

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;
}
Run Code Online (Sandbox Code Playgroud)

您可以将它用于"无限"重复,例如以这种方式:

string[] collection = { "A", "B", "C"};
var infiniteCollection = collection.RepeatWhile(s => s == s);
List<string> take1000OfInfinite = infiniteCollection.Take(1000).ToList();
Run Code Online (Sandbox Code Playgroud)

  • 我喜欢它,但是,int.MaxValue <永远 (2认同)