gpt4 book ai didi

c# - 在 C# 中将多个 IEnumerable 提要混合到一个提要中

转载 作者:行者123 更新时间:2023-12-02 17:24:46 27 4
gpt4 key购买 nike

我经常需要在我有IEnumerable<T> A的地方执行操作, IEnumerable<T> B我想创建 IEnumerable<T> C其中C将从A获取2T,然后从B获取1T,然后再次从A获取2T,然后从B获取1T,依此类推 - AABAABAAB...

C# 中是否有某种语言构造,也许有一些 LINQ 表达式可以轻松完成这一任务。

现在我编写了一个小帮助器类,使我能够做到这一点:

var C = EnumerableMixer(new int[]{2, 1}, A, B) :

    public class EnumerableMixer<T> : IEnumerable<T>
{
int[] Quantity;
IEnumerable<T>[] Args;

public EnumerableMixer(int[] quantity, params IEnumerable<T>[] args)
{
this.Quantity = quantity;
this.Args = args;
if (quantity.Length != args.Length)
throw new NotImplementedException("Quantity must have same length as number of args!");
}

IEnumerable<T> Mix
{
get
{
var available = new List<int>(Quantity.Length);
var enumerators = new List<IEnumerator<T>>(Quantity.Length);
for (int i = 0; i < Quantity.Length; ++i)
{
available.Add(i);
enumerators.Add(Args[i].GetEnumerator());
}
while (available.Count > 0)
{
for (int i = 0; i < available.Count; ++i)
{
var id = available[i];
for (int j = 0; j < Quantity[id]; ++j)
{
if (enumerators[id].MoveNext())
yield return enumerators[id].Current;
else
{
available.RemoveAt(i);
i--;
break;
}
}
}
}
}
}

#region IEnumerable<T> Members

public IEnumerator<T> GetEnumerator()
{
return Mix.GetEnumerator();
}

#endregion

#region IEnumerable Members

System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}

#endregion
}

最佳答案

版本 1

这是基于 adhie 的解决方案。它会考虑该比率并在退出该方法之前完全完成两个序列。 flag 用于跟踪最后一个循环是否产生了任何结果。当flag为假时,两个序列都被耗尽。

public IEnumerable<T> Mix<T>(IEnumerable<T> sequenceA, IEnumerable<T> sequenceB, int ratioA, int ratioB)
{
var etorA = sequenceA.GetEnumerator();
var etorB = sequenceB.GetEnumerator();
bool flag = true;

while(flag)
{
flag = false;

for(int i = 0; i < ratioA && (flag |= etorA.MoveNext()); i++)
yield return etorA.Current;

for(int i = 0; i < ratioB && (flag |= etorB.MoveNext()); i++)
yield return etorB.Current;
}
}

版本 2

与版本 1 几乎相同,但采用可变数量的序列。

public IEnumerable<T> Mix<T>(params KeyValuePair<IEnumerable<T>, uint>[] quantifiedSequences)
{
var sequences = quantifiedSequences.Select(x => new { Etor = x.Key.GetEnumerator(), Quantity = x.Value });
bool flag = true;

while(flag)
{
foreach (var sequence in sequences)
for(int i = 0; i < sequence.Quantity && (flag |= sequence.Etor.MoveNext()); i++)
yield return sequence.Etor.Current;
}
}

关于c# - 在 C# 中将多个 IEnumerable<T> 提要混合到一个提要中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25447165/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com