c# - 在 C# 中相当于 Haskell 的 Data.List.Span

标签 c# linq haskell

您好,是否已经实现了任何有效的方法来获取 Haskell Data.List.span 的功能?

span :: (a -> Bool) -> [a] -> ([a], [a])

基本上给定一个列表和一个谓词,我想在第一次出现错误谓词后将列表分成两部分。元素在测试 Falsepivot 元素之后可能会也可能不会遵守谓词,但我不在乎。

List: [1,2,3,1,2,3]
Predicate: x<3
Span:  `span  (x<3) [1,2,3,1,2,3]`   =>  `([1,2],[3,1,2,3])`

更新 我不关心第一个 false 谓词之后的元素。我只想在第一次出现 False 谓词时拆分列表。第一个 False 谓词之后的序列可以是 True,但我仍然想将其拆分。

最佳答案

如果您对使用列表感到满意,那么您可以通过源列表进行一次传递来创建两个新列表,如下所示:

public static (List<T> part1, List<T> part2) SplitListBy<T>(List<T> source, Predicate<T> splitWhen)
{
    var part1 = new List<T>();

    int i;

    for (i = 0; i < source.Count && !splitWhen(source[i]); ++i)
        part1.Add(source[i]);

    var part2 = source.GetRange(i, source.Count - i);

    return (part1, part2);
}

这应该非常高效。请注意,这使用元组返回两个列表,这需要 C# 7 或更高版本。如果您无法使用 c# 7+,则必须更改代码以使用 out 参数返回列表之一。

测试代码:

var list = new List<int>{ 1, 2, 3, 1, 2, 3 };

var (part1, part2) = SplitListBy(list, item => item >= 3);

Console.WriteLine(string.Join(", ", part1));
Console.WriteLine(string.Join(", ", part2));

输出:

1, 2
3, 1, 2, 3
<小时/>

如果您不需要两个新列表,而只想将原始列表用于一部分,而将一个新列表用于另一部分,则可以这样做:

public static List<T> SplitListBy<T>(List<T> source, Predicate<T> splitWhen)
{
    int i;

    for (i = 0; i < source.Count && !splitWhen(source[i]); ++i)
        ;

    var part2 = source.GetRange(i, source.Count - i);

    source.RemoveRange(i, source.Count - i);

    return part2;
}

测试代码非常相似:

var list = new List<int>{ 1, 2, 3, 1, 2, 3 };

var part2 = SplitListBy(list, item => item >= 3);

Console.WriteLine(string.Join(", ", list));
Console.WriteLine(string.Join(", ", part2));

(输出与其他测试代码相同。)

关于c# - 在 C# 中相当于 Haskell 的 Data.List.Span,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60415346/

相关文章:

c# - 使用 SOAP 访问数据库的最佳方式

c# - 下面的代码可以用 LINQ/lambda 重写吗

haskell - 如何在我的 `reverse` 版本中在另一个函数中本地定义一个函数 - 出现解析错误

Haskell:更好地理解代数数据类型

c# - LeadTools MaximumGlobalRasterImageMemory

c# - 从 Webdings 字体创建系统托盘图标

c# - 在C#中实现同步算法

c# - 如何最好地使用 C#/LINQ 计算派生货币汇率转换?

c# - 替换 DataColumn 中的值

linux - 在 jail 环境中运行 Haskell 程序需要什么