F#: 如何从字符串中删除前N个字符?

7

我正在尝试编写一些代码来删除字符串中的前N个字符。我可以使用命令式方式完成此操作,但我希望看到它在函数式编程精神下完成。作为F#和函数式编程的新手,我遇到了一些困难...


2
需要注意的是,由于F#字符串是不可变的,因此您无法从现有字符串实例中删除字符。您只能创建一个新的字符串实例,而不包含这些字符。 - Pavel Minaev
2
"由于 F# 字符串是不可变的" 并不是 100% 准确的。F# 使用的 System.String 类型在所有 .NET 应用程序中都是不可变的。唯一支持的可变字符串类型是 System.Text 命名空间中的 StringBuilder。 - Chris Smith
5个回答

29
"Hello world".[n..];;

3

正如@Jeff所展示的,您可以用六个字符来实现这一点,因此这不一定是一个最好的问题,以了解如何“在函数式编程精神下完成它”。

我展示另一种方式,它不是特别“函数式的”(因为它使用数组,但至少它不会改变任何东西),但至少显示了一组步骤。

let s = "Hello, world!"
// get array of chars
let a = s.ToCharArray()
// get sub array (start char 7, 5 long)
let a2 = Array.sub a 7 5
// make new string
let s2 = new string(a2)
printfn "-%s-" s2  // -world-

2
"Hello world".Substring 3

0
let rec remove_first_n (str:string) (n:int) =
  match str, n with
  | _, n when n <= 0 -> str
  | "", _ -> ""
  | _ -> remove_first_n (str.Remove(0,1)) (n-1)

1
+1 表示展示了典型的递归函数结构,但是 -2 是因为提出了一个 O(n) 的解决方案来解决一个 O(1) 的问题。 - Brian
抱歉,我的意思是O(N^2)与O(N)的比较。 - Brian

0

另一种方法(也不是特别功能性的)。实际上它使用了两个世界的特性:变异和lambda:

let remove_first_n (s:string) (n:int) =
    let arr = Array.create (s.Length-n) '0'
    String.iteri (fun i c -> if i>=n then arr.[i-n] <- c else ()) s
    new string(arr)

话虽如此,我认为最好的方法是Jeff的解决方案。

还有一件事需要记住的是,在.NET中字符串是不可变的(一旦构建了字符串值就不能修改),而F#字符串实际上是.NET字符串。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接