gpt4 book ai didi

c# - 寻找特定的可枚举运算符序列 : TakeWhile(! ) + Concat Single

转载 作者:太空狗 更新时间:2023-10-29 21:47:08 26 4
gpt4 key购买 nike

给定一个 Enumerable,我想 Take() 所有元素直到并包括终止符(如果找不到终止符则抛出异常)。像这样的东西:

list.TakeWhile(v => !condition(v)).Concat(list.Single(condition))

..除了不蹩脚。只想走一遍。

对于 .NET 4 和 Rx 中的当前运算符,这是否可以简洁地实现,或者我是否需要编写一个新的运算符?

写操作符比写这个问题花费的时间更少(虽然我认为一半的时间会弄清楚如何命名这个函数),但我只是不想复制已经存在的东西。

更新

好的,这是接线员。非常令人兴奋,我知道。无论如何,可以从内置运算符构建它吗?

    public static IEnumerable<T> TakeThroughTerminator<T>([NotNull] this IEnumerable<T> @this, Func<T, bool> isTerminatorTester)
{
foreach (var item in @this)
{
yield return item;
if (isTerminatorTester(item))
{
yield break;
}
}

throw new InvalidOperationException("Terminator not found in list");
}

最佳答案

没有内置函数可以有效地执行此类操作。人们通常需要获得满足条件的元素和不满足条件的元素。您必须自己编写。

但是您可以使用现有方法构建它,它不会那么有效,因为您需要以某种方式保持状态只会使您的代码复杂化。我不会容忍这种查询,因为它违背了 LINQ 的理念,我会自己编写。但是既然你问了:

var list = Enumerable.Range(0, 10);
Func<int, bool> condition = i => i != 5;
int needed = 1;
var query = list.Where(item => condition(item)
? needed > 0
: needed-- > 0)
.ToList(); // this might cause problems
if (needed != 0)
throw new InvalidOperationException("Sequence is not properly terminated");

然而,这有其自身的问题,无法很好地解决。处理这个问题的正确方法是手动编写所有代码(不使用 LINQ)。这会给你完全相同的行为。

public static IEnumerable<TSource> TakeWhileSingleTerminated<TSource>(
this IEnumerable<TSource> source,
Func<TSource, bool> predicate)
{
var hasTerminator = false;
var terminator = default(TSource);
foreach (var item in source)
{
if (!hasFailed)
{
if (predicate(item))
yield return item;
else
{
hasTerminator = true;
terminator = item;
}
}
else if (!predicate(item))
throw new InvalidOperationException("Sequence contains more than one terminator");
}
if (!hasTerminator)
throw new InvalidOperationException("Sequence is not terminated");
yield return terminator;
}

经过深思熟虑后,我会说很难最有效地实现原始查询,因为它有相互冲突的要求。您将提前终止的 TakeWhile() 与不能提前终止的 Single() 混合在一起。复制最终结果是可能的(正如我们在这里都尝试过的那样),但如果不对代码进行重大更改,行为就无法复制。如果目标是只获取第一个失败的项目,那么这将是完全可能和可复制的,但由于它不是,您将只需要处理此查询存在的问题。

p.s.,我认为仅凭我对这个答案所做的编辑就可以看出这是多么重要。希望这是我最后一次编辑。

关于c# - 寻找特定的可枚举运算符序列 : TakeWhile(! ) + Concat Single,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5479375/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com