2017-10-11 6 views
3

私は最初に特定の要素をスキップする必要がある値のIEnumerableを持っています。これはSkipWhileを使用しています。しかし、私は間違いなく少なくとも1つの要素を必要としている(シーケンスには少なくとも1つの要素が含まれていても)。すべての要素が述語を通過すると(つまり、すべての要素がスキップされます)、最後の要素のみを取得したいと思います。 LINQはのための組み込みメソッドを提供していませんLINQ SkipWhile - 少なくとも1つを取る

+0

'items'何ですか?それは 'List 'です。[.Last()は既にO(1)時間で実行されています](https://stackoverflow.com/questions/1377864/what-is-the-performance-of-the-last-extension -method-for-listt)、あなたは一度だけあなたのリストを反復しています –

+0

そして、これを任意の述語で動作させたいなら、あなたのリストを少なくとも1回は反復することはできません。 –

+0

私はそれがそれほど高価ではないかどうかはわかりませんが、IEnumerable .Reverse()を使用して、それを通って最初の一致を返します。 –

答えて

5

:これは(それは私がそれを阻止したいのですが、二回のシーケンスを反復する必要のように高価な)

items.SkipWhile(/* my condition */).FallbackIfEmpty(items.Last()) 

のような高価なトリックなしで何とか可能ですこれはあなた自身の拡張子を書くことができます。

この実装は、Microsoftのreference codeから、大部分が、持ち上げられ:

public static IEnumerable<TSource> SkipWhileOrLast<TSource>(
    this IEnumerable<TSource> source, 
    Func<TSource, bool> predicate 
) { 
    bool yielding = false; 
    TSource last = default(TSource); 
    bool lastIsAssigned = false; 
    foreach (TSource element in source) { 
     if (!yielding && !predicate(element)) { 
      yielding = true; 
     } 
     if (yielding) { 
      yield return element; 
     } 
     lastIsAssigned = true; 
     last = element; 
    } 
    if (!yielding && lastIsAssigned) { 
     yield return last; 
    } 
} 
関連する問題