Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/306.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 帮助实现ZipWithRatio扩展方法_C#_Linq_Extension Methods - Fatal编程技术网

C# 帮助实现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

我试图找到一种优雅的方法来编写一个扩展方法,该方法可能被称为MergeWithRatio或ZipWithRatio

我希望它有这个签名

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;
                }
            }
        }
    }
}