Mah*_*dsi 7 c# linq algorithm ienumerable enumerator
让我们假设您有一个函数返回一个延迟枚举的对象:
struct AnimalCount
{
int Chickens;
int Goats;
}
IEnumerable<AnimalCount> FarmsInEachPen()
{
....
yield new AnimalCount(x, y);
....
}
Run Code Online (Sandbox Code Playgroud)
您还有两个消耗两个独立IEnumerable
s的函数,例如:
ConsumeChicken(IEnumerable<int>);
ConsumeGoat(IEnumerable<int>);
Run Code Online (Sandbox Code Playgroud)
如何调用ConsumeChicken
和ConsumeGoat
不FarmsInEachPen()
预先转换ToList()因为它可能有两个zillion记录,b)没有多线程.
基本上:
ConsumeChicken(FarmsInEachPen().Select(x => x.Chickens));
ConsumeGoats(FarmsInEachPen().Select(x => x.Goats));
Run Code Online (Sandbox Code Playgroud)
但是没有强制双重枚举.
我可以使用多线程来解决它,但是每个列表的缓冲队列都会变得不必要地复杂化.
所以我正在寻找一种方法将AnimalCount
枚举器分成两个int
枚举器而不进行全面评估AnimalCount
.在锁定步骤中一起运行ConsumeGoat
并没有问题ConsumeChicken
.
我可以感觉到解决方案,但我并不完全在那里.我正在考虑一个辅助函数,它返回一个IEnumerable
被输入的函数,ConsumeChicken
每次使用迭代器时,它在内部调用ConsumeGoat
,从而在锁步中执行这两个函数.当然,除了我不想ConsumeGoat
多次打电话..
我想通了,这在很大程度上要归功于@Lee 让我走上的道路。
您需要在两个 zip 之间共享一个枚举器,并使用适配器函数将正确的元素投影到序列中。
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);
}
Run Code Online (Sandbox Code Playgroud)