一串拆分"????‍????‍????‍????" "????"通常会导致["????‍"; "‍????‍????"],分解视觉角色.

我想要一个可以返回[????‍????‍????‍????"],而不是分解视觉字符.据我所知,这些"视觉字符"在.NET世界中被称为TextElements,或在其他地方被称为EGCs(扩展的图形集).

这里有一些细节:https://docs.microsoft.com/en-us/dotnet/api/system.globalization.textelementenumerator?view=net-6.0

我提出了一个糟糕的解决方案:

let ecgStringSplit'
  (elements : string list)
  (sep : string list)
  : string list =
  let startsWithSeparator (str : string list) =
    sep = (str |> List.truncate sep.Length)

  let mutable result = []
  let mutable inProgress = []

  let rec recursiveFn (elementsRemaining : string list) : unit =
    if elementsRemaining = [] then
      result <- result @ [ inProgress |> String.concat "" ]
    elif startsWithSeparator elementsRemaining then
      result <- result @ [ inProgress |> String.concat "" ]
      inProgress <- []
      recursiveFn (List.skip sep.Length elementsRemaining)
    else
      inProgress <- inProgress @ [ elementsRemaining.Head ]
      recursiveFn elementsRemaining.Tail

  recursiveFn elements

  result

let toEgcList (s : string) : string list =
  seq {
    let tee = System.Globalization.StringInfo.GetTextElementEnumerator(s)

    while tee.MoveNext() do
      yield tee.GetTextElement()
  } |> Seq.toList

let ecgStringSplit (str: string) (sep: string) =
  ecgStringSplit' (toEgcList str) (toEgcList sep)

ecgStringSplit "Hello world 1" " " |> printfn "%A" // results in ["Hello"; "world"; "1"]
ecgStringSplit "????‍????‍????‍????" "????" |> printfn "%A" // results in ["????‍????‍????‍????"]

除了将其重构为不使用可变值之类的,我想知道我是否缺少一个更简单的解决方案来解决这个问题?

我很乐意采用一个C#解决方案,我可以将其移植到F.

编辑:使用F#列表以外的其他东西肯定会有助于提高性能.

推荐答案

OP的重构形式

let ecgStringSplit str sep =
  let startsWithSeparator str = sep = (str |> List.truncate sep.Length)

  let result = ResizeArray<string>()

  let rec r (strRemaining : List<string>, inProgress) : unit =
    if strRemaining = [] then
      result |> ResizeArray.append (inProgress.ToString())
    elif startsWithSeparator strRemaining then
      result |> ResizeArray.append (inProgress.ToString())

      r (List.skip sep.Length strRemaining, StringBuilder())
    else
      r (strRemaining.Tail, inProgress.Append(strRemaining.Head))

  r (str, StringBuilder())

  result |> ResizeArray.toList

.net相关问答推荐

.NET Blazor-使用子组件中的处理程序方法进行双向数据绑定

.NET最小API BadRequest响应不返回正文

从删除项目时重新索引的列表中删除项目的最佳算法是什么?

Msbuild try 构建 msbuild.exe 而不是我的 .csproj 文件

在生产中使用实体框架(代码优先)迁移

为 XML 编码文本数据的最佳方法

使用 Task.Factory.StartNew 传递方法参数

获取 .NET Framework 目录路径

如何在 C# 中仅设置 DateTime 变量的时间部分

在 C# 中与块等效?

DataGridView 在我的两个屏幕之一上的可怕重绘性能

您可以使用 Xamarin 开发 Linux 应用程序吗?

beforefieldinit 标志有什么作用?

读取 XML(从字符串)并获取一些字段 - 读取 XML 时出现问题

具有不同身份验证标头的 HttpClient 单个实例

绑定在代码隐藏中定义的对象

根据条件从列表中删除项目

记录器包装器最佳实践

System.Array.CopyTo() 和 System.Array.Clone() 之间的区别

.NET Remoting 真的被弃用了吗?