【问题标题】:LINQ SkipWhile - Take at least oneLINQ SkipWhile - 至少取一个
【发布时间】:2017-10-12 02:33:17
【问题描述】:

我有一个IEnumerable 的值,我需要在开始时跳过某些元素,为此我使用SkipWhile。但是,我绝对需要至少一个元素(假设序列甚至包含至少一个开始的元素)。如果所有元素都通过谓词(即所有元素都被跳过),我只想得到最后一个元素。如果没有像

这样的昂贵技巧,这是否可能
items.SkipWhile(/* my condition */).FallbackIfEmpty(items.Last())

(昂贵的:它需要迭代序列两次,我想防止这种情况发生)

【问题讨论】:

  • 什么是items?它是一个List<T>.Last() already runs in O(1) time,而且你只遍历你的列表一次
  • 如果你想让它与任何谓词一起工作,你不能绕过至少一次迭代你的列表。
  • 我不确定它是否更便宜,但您可以使用 IEnumerable.Reverse() 然后正常遍历它,返回第一个匹配项。
  • @SamIam 不幸的是它不是,它被预先过滤并保持为 IEnumerable。
  • @tkausl 那么,它是什么?它从何而来? IEnumerable 是一个接口,它是一个 IEnumerable 可能意味着什么

标签: c# linq


【解决方案1】:

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

【讨论】:

    猜你喜欢
    • 2022-01-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-02
    • 1970-01-01
    • 2013-10-03
    相关资源
    最近更新 更多