2017-10-11 166 views
3

我有一个IEnumerable的值,我需要在开始时跳过某些元素,为此我使用SkipWhile。但是,我绝对需要至少一个元素(因为该序列甚至包含至少一个元素开头)。如果所有元素都传递谓词(即所有元素都被跳过),我只想得到最后一个元素。这在某种程度上可能无需昂贵的技巧,比如LINQ SkipWhile - 至少有一个

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

(昂贵的:它需要两次迭代的顺序,我想阻止)

+0

是什么'items'?它是一个'List ',[.Last()已经在O(1)时间运行](https://stackoverflow.com/questions/1377864/what-is-the-performance-of-the-last-extension -method-for-listt),并且你只遍历你的列表一次 –

+0

如果你想让它和任何谓词一起工作,你不能绕过你的列表迭代至少一次。 –

+0

我不确定它是否更便宜,但是您可以使用IEnumerable .Reverse(),然后正常浏览它,返回第一个匹配项。 –

回答

5

LINQ不提供内置方法这,但你可以写你自己的扩展。

此实现提升,在大多数情况下,从微软的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; 
    } 
} 
相关问题