我正在尝试找一种优雅的方法来编写一个可能被称为MergeWithRatio或ZipWithRatio的扩展方法。
我希望它有这个签名..
public static IEnumerable<T> MergeWithRatio<T>(this IEnumerable<T> source, IEnumerable<T> mergeSequence, int ratio)
{
..
}
示例第一。
var source = new[]{1,2,3,4,5,6,7,8,9};
var mergeSeq = new[]{100,200};
var result = source.MergeWithRatio(mergeSeq, 3).ToArray();
结果现在包含[1,2,100,3,4,200,5,6,100,7,8,200,9]
总结: 当/ if结束时,mergeSeq循环,当'source'为空时,屈服停止。
如果可能,我会优先考虑解决方案是否懒惰但不是必需的。
任何想法或指示?
答案 0 :(得分:2)
这将起作用并返回预期的输出:
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;
}
}
}
}
答案 1 :(得分: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;
}
}
}
}
}
答案 2 :(得分:0)
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;
}
}
}
}
加上对mergeSequenceEnumerator.MoveNext()
,ratio
输入值`等的一些检查