1

我得到了这个在很多情况下都使用的好方法。

internal static IEnumerable<TResult> RoundTrip<TSource, TResult>
 (this IEnumerable<TSource> e, Func<TSource, TSource, TResult> currentNextAction)
{
    using (IEnumerator<TSource> enumer = e.GetEnumerator())
    {
        if (!enumer.MoveNext())
            yield break;

        bool flag = true;
        TSource first = enumer.Current;

        do
        {
            TSource current = enumer.Current;
            TSource next = (flag = enumer.MoveNext()) ? enumer.Current : first;
            yield return currentNextAction(current, next);
        } while (flag);
    }
}

我在MSDN中寻找了一些内置的替代品,但找不到它们。有没有?

而且,这段代码有什么可以改进的吗?

编辑:不可枚举方法的新代码。

internal static IEnumerable<TResult> RoundTrip<TSource, TResult>
 (this IEnumerable<TSource> e, Func<TSource, TSource, TResult> currentNextAction)
{
    bool flag = false;
    TSource first = default(TSource);
    TSource previous = default(TSource);

    foreach (TSource item in e)
    {
        if (!flag)
        {
            flag = true;
            first = previous = item;
            continue;
        }

        yield return currentNextAction(item, previous);
        previous = item;
    }

    if (flag)
        yield return currentNextAction(previous, first);
    else
        yield break;
}

(顺便说一下,我喜欢第一个)

4

2 回答 2

1

你有 Enumerable.Zip

var result = e.Zip(e.Skip(1).Concat(e.Take(1)), action)

它当然会枚举序列两次(+1 元素),除非你先列出一个列表

编辑:错过了往返

于 2012-11-07T13:06:13.327 回答
1

没有内置任何东西,但你可以真正简化它:

var lst = e.ToList();

lst.Add(lst[0]);
var result = lst.Take(lst.Count - 1).Select((x, i) => action(x, lst[i + 1]));
于 2012-11-07T12:51:00.747 回答