C# 帮助实现ZipWithRatio扩展方法
我试图找到一种优雅的方法来编写一个扩展方法,该方法可能被称为MergeWithRatio或ZipWithRatio 我希望它有这个签名C# 帮助实现ZipWithRatio扩展方法,c#,linq,extension-methods,C#,Linq,Extension Methods,我试图找到一种优雅的方法来编写一个扩展方法,该方法可能被称为MergeWithRatio或ZipWithRatio 我希望它有这个签名 public static IEnumerable<T> MergeWithRatio<T>(this IEnumerable<T> source, IEnumerable<T> mergeSequence, int ratio) { .. } 结果现在包含[1,2100,3,4200,5,6100,7,82
public static IEnumerable<T> MergeWithRatio<T>(this IEnumerable<T> source, IEnumerable<T> mergeSequence, int ratio)
{
..
}
结果现在包含[1,2100,3,4200,5,6100,7,8200,9]
总结:
mergeSeq在完成时/如果完成时循环,而屈服在“source”为空时停止
如果可能的话,我更希望解决方案是懒惰的,但这不是一个要求
任何想法或指针?公共静态IEnumerable MergeWithRatio(此IEnumerable源、IEnumerable mergeSequence、int ratio)
public static IEnumerable<T> MergeWithRatio<T>(this IEnumerable<T> source, IEnumerable<T> mergeSequence, int ratio)
{
using (IEnumerator<T> sourceEnumerator = source.GetEnumerator(),
mergeSequenceEnumerator = mergeSequence.GetEnumerator())
{
int i = 1;
while (sourceEnumerator.MoveNext())
{
yield return sourceEnumerator.Current;
i++;
if (i == ratio)
{
if (!mergeSequenceEnumerator.MoveNext())
{
mergeSequenceEnumerator.Reset();
mergeSequenceEnumerator.MoveNext();
}
yield return mergeSequenceEnumerator.Current;
i = 1;
}
}
}
}
{
使用(IEnumerator sourceEnumerator=source.GetEnumerator(),
mergeSequenceEnumerator=mergeSequence.GetEnumerator()
{
int i=1;
while(sourceEnumerator.MoveNext())
{
产生返回sourceEnumerator.Current;
i++;
如果(i==比率)
{
如果(!mergeSequenceEnumerator.MoveNext())
{
mergeSequenceEnumerator.Reset();
mergeSequenceEnumerator.MoveNext();
}
产生返回mergeSequenceEnumerator.Current;
i=1;
}
}
}
}
加上对
mergeSequenceEnumerator.MoveNext(),比率
输入值等的一些检查。这将起作用并返回预期的输出:
public static IEnumerable<T> MergeWithRatio<T>(this IEnumerable<T> source, IEnumerable<T> mergeSequence, int ratio)
{
int currentRatio = 1;
bool mergeSequenceIsEmpty = !mergeSequence.Any();
using (var mergeEnumerator = mergeSequence.GetEnumerator())
{
foreach (var item in source)
{
yield return item;
currentRatio++;
if (currentRatio == ratio && !mergeSequenceIsEmpty)
{
if (!mergeEnumerator.MoveNext())
{
mergeEnumerator.Reset();
mergeEnumerator.MoveNext();
}
yield return mergeEnumerator.Current;
currentRatio = 1;
}
}
}
}
公共静态IEnumerable MergeWithRatio(此IEnumerable源、IEnumerable mergeSequence、int-ratio)
{
电流比率=1;
bool mergeSequenceIsEmpty=!mergeSequence.Any();
使用(var mergeEnumerator=mergeSequence.GetEnumerator())
{
foreach(源中的var项)
{
收益回报项目;
电流比++;
if(currentRatio==比率&&!mergeSequenceIsEmpty)
{
如果(!mergeEnumerator.MoveNext())
{
mergeEnumerator.Reset();
mergeEnumerator.MoveNext();
}
产生返回合并枚举数。当前;
电流比=1;
}
}
}
}
以下是我的实现:
public static IEnumerable<T> MergeWithRatio<T>(this IEnumerable<T> source, IEnumerable<T> mergeSequence, int ratio)
{
if (source == null)
{
throw new ArgumentNullException("source");
}
if (mergeSequence == null)
{
throw new ArgumentNullException("mergeSequence");
}
if (ratio <= 1)
{
throw new ArgumentOutOfRangeException("ratio must be greater one.");
}
return MergeWithRatioImpl(source, mergeSequence, ratio);
}
private static IEnumerable<T> MergeWithRatioImpl<T>(this IEnumerable<T> source, IEnumerable<T> mergeSequence, int ratio)
{
bool mergeSequenceContainsElements = true;
int i = 1;
ratio--;
using (var sourceEnumerator = source.GetEnumerator())
using (var mergeSequenceEnumerator = mergeSequence.GetEnumerator())
{
while (sourceEnumerator.MoveNext())
{
yield return sourceEnumerator.Current;
if (i++ % ratio == 0)
{
if (!mergeSequenceEnumerator.MoveNext())
{
// ToDo: Should we cache the current values for the case the
// enumerator can't be reset?
mergeSequenceEnumerator.Reset();
mergeSequenceContainsElements = mergeSequenceEnumerator.MoveNext();
}
if (mergeSequenceContainsElements)
{
yield return mergeSequenceEnumerator.Current;
}
}
}
}
}
公共静态IEnumerable MergeWithRatio(此IEnumerable源、IEnumerable mergeSequence、int-ratio)
{
if(source==null)
{
抛出新的ArgumentNullException(“源”);
}
if(mergeSequence==null)
{
抛出新ArgumentNullException(“合并序列”);
}
如果(如果可能,请不要忘记处理这两个迭代器。source
的迭代器将由foreach
正确处理,如果可能,请不要忘记也处理mergeEnumerator
。您尚未指定结果是否可以/应该以mergeSequence
+1中的一项结束,以进行错误检查和分离。)将延迟的执行转换为一个单独的方法。@juharr:是的,多亏了Jon和is。
public static IEnumerable<T> MergeWithRatio<T>(this IEnumerable<T> source, IEnumerable<T> mergeSequence, int ratio)
{
if (source == null)
{
throw new ArgumentNullException("source");
}
if (mergeSequence == null)
{
throw new ArgumentNullException("mergeSequence");
}
if (ratio <= 1)
{
throw new ArgumentOutOfRangeException("ratio must be greater one.");
}
return MergeWithRatioImpl(source, mergeSequence, ratio);
}
private static IEnumerable<T> MergeWithRatioImpl<T>(this IEnumerable<T> source, IEnumerable<T> mergeSequence, int ratio)
{
bool mergeSequenceContainsElements = true;
int i = 1;
ratio--;
using (var sourceEnumerator = source.GetEnumerator())
using (var mergeSequenceEnumerator = mergeSequence.GetEnumerator())
{
while (sourceEnumerator.MoveNext())
{
yield return sourceEnumerator.Current;
if (i++ % ratio == 0)
{
if (!mergeSequenceEnumerator.MoveNext())
{
// ToDo: Should we cache the current values for the case the
// enumerator can't be reset?
mergeSequenceEnumerator.Reset();
mergeSequenceContainsElements = mergeSequenceEnumerator.MoveNext();
}
if (mergeSequenceContainsElements)
{
yield return mergeSequenceEnumerator.Current;
}
}
}
}
}