问题描述
让我们假设你有一个函数返回一个懒洋洋地枚举对象:
Lets assume you have a function that returns a lazily-enumerated object:
struct AnimalCount
{
int Chickens;
int Goats;
}
IEnumerable<AnimalCount> FarmsInEachPen()
{
....
yield new AnimalCount(x, y);
....
}
您还可以消耗两个功能两个不同的的IEnumerable
S,例如:
You also have two functions that consume two separate IEnumerable
s, for example:
ConsumeChicken(IEnumerable<int>);
ConsumeGoat(IEnumerable<int>);
你怎么能叫 ConsumeChicken
和 ConsumeGoat
无)转换 FarmsInEachPen()
了ToList()事前,因为它可能有两个数不胜数的记录,B)没有多线程。
How can you call ConsumeChicken
and ConsumeGoat
without a) converting FarmsInEachPen()
ToList() beforehand because it might have two zillion records, b) no multi-threading.
基本上是:
ConsumeChicken(FarmsInEachPen().Select(x => x.Chickens));
ConsumeGoats(FarmsInEachPen().Select(x => x.Goats));
但不强制双重枚举。
But without forcing the double enumeration.
我可以多线程解决它,但它被不必要地复杂化了缓冲队列为每个列表。
I can solve it with multithread, but it gets unnecessarily complicated with a buffer queue for each list.
所以我在寻找一种方式来 AnimalCount
枚举分成两个 INT
调查员没有充分评估 AnimalCount
。目前运行没有问题 ConsumeGoat
和 ConsumeChicken
一起在锁步。
So I'm looking for a way to split the AnimalCount
enumerator into two int
enumerators without fully evaluating AnimalCount
. There is no problem running ConsumeGoat
and ConsumeChicken
together in lock-step.
我能感觉到解刚走出我的把握,但我不能令人信服。我沿着一个辅助函数返回一个的IEnumerable行思
被送入 ConsumeChicken
每一次的迭代器时,它在内部调用 ConsumeGoat
,因此在执行锁步的两个功能。除,当然,我也不想叫 ConsumeGoat
不止一次。
I can feel the solution just out of my grasp but I'm not quite there. I'm thinking along the lines of a helper function that returns an IEnumerable
being fed into ConsumeChicken
and each time the iterator is used, it internally calls ConsumeGoat
, thus executing the two functions in lock-step. Except, of course, I don't want to call ConsumeGoat
more than once..
推荐答案
我想通了,由于道路在很大程度上归功于该@Lee把我的。
I figured it out, thanks in large part due to the path that @Lee put me on.
您需要两个拉链之间共享一个枚举器,并使用适配器函数来预测正确的元素插入的顺序。
You need to share a single enumerator between the two zips, and use an adapter function to project the correct element into the sequence.
private static IEnumerable<object> ConsumeChickens(IEnumerable<int> xList)
{
foreach (var x in xList)
{
Console.WriteLine("X: " + x);
yield return null;
}
}
private static IEnumerable<object> ConsumeGoats(IEnumerable<int> yList)
{
foreach (var y in yList)
{
Console.WriteLine("Y: " + y);
yield return null;
}
}
private static IEnumerable<int> SelectHelper(IEnumerator<AnimalCount> enumerator, int i)
{
bool c = i != 0 || enumerator.MoveNext();
while (c)
{
if (i == 0)
{
yield return enumerator.Current.Chickens;
c = enumerator.MoveNext();
}
else
{
yield return enumerator.Current.Goats;
}
}
}
private static void Main(string[] args)
{
var enumerator = GetAnimals().GetEnumerator();
var chickensList = ConsumeChickens(SelectHelper(enumerator, 0));
var goatsList = ConsumeGoats(SelectHelper(enumerator, 1));
var temp = chickensList.Zip(goatsList, (i, i1) => (object) null);
temp.ToList();
Console.WriteLine("Total iterations: " + iterations);
}
这篇关于&QUOT;解压缩&QUOT;在C#或最好的选择了IEnumerable动态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!