是否有可能克隆一个IEnumerable< T>例如,节省了迭代状态的副本?有可能、副本、节省、状态

2023-09-03 06:57:37 作者:曲未终人已散

我想创建一个的IEnumerator℃的复印件; T> ,这样我可以从集合在特定位置重新启动枚举过程。很显然,没有任何好处这样做对于实现的IList ,因为我们记得感兴趣的索引。集合

I'd like to create a copy of an IEnumerator<T> so that I can restart the enumeration process from a particular location in the collection. Clearly, there is no benefit to doing so for collections that implement IList, since we can remember the index of interest.

有一个聪明的方法来完成这项任务使用收益率的组合语句和LINQ的功能?我无法找到一个合适的克隆()方法复制枚举,并且想避免使用 Enumerable.Skip()来重新定位一个新的枚举到所需的恢复点。

Is there a clever way to accomplish this task using a combination of yield statements and Linq functions? I could not find a suitable Clone() method to copy the enumerator, and would like to avoid using Enumerable.Skip() to reposition a new enumerator to the desired resumption point.

另外,我想保持的解决方案,尽可能地通用,而不必依赖于国家的任何具体的集合。

Also, I'd like to keep the solutions as generic as possible, and not have to depend on state from any concrete collections.

推荐答案

你可以做的最好的是写东西,保持一个缓冲区(可能是问答LT; T&GT; )从一个消费的数据,而不是其他的(这将导致混乱/昂贵的,如果你前进一个迭代器1M的位置,但单独留在家中的除外)。我的真正的认为你会更好重新思考设计的,虽然,只是用的GetEnumerator()(即另一个的foreach )重新开始 - 或者缓冲区中的数据(如短)的列表/阵列/不管

The best you could do is write something that keeps a buffer (perhaps a Queue<T>) of the data consumed from one and not the other (which would get messy/expensive if you advanced one iterator by 1M positions, but left the other alone). I really think you would be better off rethinking the design, though, and just using GetEnumerator() (i.e. another foreach) to start again - or buffer the data (if short) in a list/array/whatever.

没有什么高雅内置的。

更新:也许这里一个有趣的选择设计是 PushLINQ ;而不是克隆的迭代器,它允许多个东西来的消耗的相同数据馈送的同时

Update: perhaps an interesting alternative design here is "PushLINQ"; rather than clone the iterator, it allows multiple "things" to consume the same data-feed at the same time.

在这个例子中(乔恩的页面解除)我们计算的并行多聚集:

In this example (lifted from Jon's page) we calculate multiple aggregates in parallel:

// Create the data source to watch
DataProducer<Voter> voters = new DataProducer<Voter>();

// Add the aggregators
IFuture<int> total = voters.Count();
IFuture<int> adults = voters.Count(voter => voter.Age >= 18);
IFuture<int> children = voters.Where(voter => voter.Age < 18).Count();
IFuture<int> youngest = voters.Min(voter => voter.Age);
IFuture<int> oldest = voters.Select(voter => voter.Age).Max();

// Push all the data through
voters.ProduceAndEnd(Voter.AllVoters());

// Write out the results
Console.WriteLine("Total voters: {0}", total.Value);
Console.WriteLine("Adult voters: {0}", adults.Value);
Console.WriteLine("Child voters: {0}", children.Value);
Console.WriteLine("Youngest vote age: {0}", youngest.Value);
Console.WriteLine("Oldest voter age: {0}", oldest.Value);
 
精彩推荐
图片推荐