gpt4 book ai didi

c# - 使用 LINQ 延迟分区序列

转载 作者:太空狗 更新时间:2023-10-29 21:34:09 25 4
gpt4 key购买 nike

我有以下扩展方法来查找序列中的元素,然后返回两个 IEnumerable<T> s:一个包含该元素之前的所有元素,一个包含该元素及其后面的所有元素。如果该方法是惰性的,我会更喜欢,但我还没有找到一种方法来做到这一点。谁能想出解决办法?

public static PartitionTuple<T> Partition<T>(this IEnumerable<T> sequence, Func<T, bool> partition)
{
var a = sequence.ToArray();
return new PartitionTuple<T>
{
Before = a.TakeWhile(v => !partition(v)),
After = a.SkipWhile(v => !partition(v))
};
}

正在做 sequence.ToArray()立即击败懒惰要求。然而,如果没有那条线,一个昂贵的迭代 sequence可以迭代两次。而且,根据调用代码的作用,还有很多次。

最佳答案

您可以使用 Lazy 对象来确保在迭代两个分区之一之前源序列不会转换为数组:

public static PartitionTuple<T> Partition<T>(
this IEnumerable<T> sequence, Func<T, bool> partition)
{
var lazy = new Lazy<IEnumerable<T>>(() => sequence.ToArray());
return new PartitionTuple<T>
{
Before = lazy.MapLazySequence(s => s.TakeWhile(v => !partition(v))),
After = lazy.MapLazySequence(s => s.SkipWhile(v => !partition(v)))
};
}

我们将使用此方法来延迟评估惰性直到序列本身被迭代:

public static IEnumerable<TResult> MapLazySequence<TSource, TResult>(
this Lazy<IEnumerable<TSource>> lazy,
Func<IEnumerable<TSource>, IEnumerable<TResult>> filter)
{
foreach (var item in filter(lazy.Value))
yield return item;
}

关于c# - 使用 LINQ 延迟分区序列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19982113/

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