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

そのために組み込まれているものはありませんが、実際に単純化することができます。

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 に答える
1

Enumerable.Zipがあります

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

もちろん、最初にリストを作成しない限り、シーケンスを2回(+1要素)列挙します。

編集:往復を逃した

于 2012-11-07T13:06:13.327 に答える