F# - 从字符数组中删除后续重复项(无序)
我正在努力学习 F#。我需要一些关于简单 soundex 表达式的帮助。 我正在使用以下规则集进行简化(也称为美式)soundex:
1.) Assign characters to classes
2.) Remove duplicate values here, e.g. 222 becomes 2
3.) Replace first encoded char with first char
4.) Remove nulls
5.) Truncate ot pad to totally 4 characters
目前我陷入了规则编号。 2.我正在考虑使用递归表达式。 由于我目前是 F# 的新手,我将尝试向您寻求一个优雅的解决方案来解决我的问题。也许我将文本翻译为 soundex 的整个方法偏离了目标?
任何建议将不胜感激:)
这是我的代码:
let Simplified (name:string) =
let ca = name.ToLower().ToCharArray()
new string(
Array.map(
fun e ->
match e with
| 'a' | 'e' | 'i' | 'o' | 'u' | 'y' | 'w' | 'h' -> '0'
| 'b' | 'f' | 'p' | 'v' -> '1'
| 'c' | 's' | 'k' | 'g' | 'j' | 'q' | 'x' | 'z' -> '2'
| 'd' | 't' -> '3'
| 'l' -> '4'
| 'm' | 'n' -> '5'
| 'r' -> '6'
| _ -> ' '
) ca
//|> fun s -> TODO: Remove duplicates here
|> fun s -> Array.set s 0 (ca.[0])
Array.choose(fun e -> if e <> '0' then Some(e) else None) s
)
|> fun s -> (
match s.Length with
| x when x < 3 -> s.PadRight(4, '0')
| _ -> s.Substring(0, 4)
).ToUpper()
I am trying to learn F#. And I need som help with a simple soundex expression.
I am using the following ruleset for Simplified (also called American) soundex:
1.) Assign characters to classes
2.) Remove duplicate values here, e.g. 222 becomes 2
3.) Replace first encoded char with first char
4.) Remove nulls
5.) Truncate ot pad to totally 4 characters
Currently I am stuck on rule no. 2. I was thinking of using a recursive expression.
As I am currently a n00b on F# I will try to ask you for an elegant solution to my problem.Maybe my entire approach to translate text to soundex is off target?
Any suggestions will be greatly appreciated :)
Here is my code:
let Simplified (name:string) =
let ca = name.ToLower().ToCharArray()
new string(
Array.map(
fun e ->
match e with
| 'a' | 'e' | 'i' | 'o' | 'u' | 'y' | 'w' | 'h' -> '0'
| 'b' | 'f' | 'p' | 'v' -> '1'
| 'c' | 's' | 'k' | 'g' | 'j' | 'q' | 'x' | 'z' -> '2'
| 'd' | 't' -> '3'
| 'l' -> '4'
| 'm' | 'n' -> '5'
| 'r' -> '6'
| _ -> ' '
) ca
//|> fun s -> TODO: Remove duplicates here
|> fun s -> Array.set s 0 (ca.[0])
Array.choose(fun e -> if e <> '0' then Some(e) else None) s
)
|> fun s -> (
match s.Length with
| x when x < 3 -> s.PadRight(4, '0')
| _ -> s.Substring(0, 4)
).ToUpper()
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
如果您想删除后续的重复项(zeuxcg 解决方案中的第二个选项),那么您也可以直接将其实现为递归函数(使用累加器参数)。这很好地演示了模式匹配,因此在学习 F# 时尝试一下是件好事:
该版本适用于列表,但由于您正在使用数组,因此您可能需要命令式版本。您可以使用这样的序列表达式:
作为旁注,我发现您的语法有点难以理解。我认为编写
... |> 不是一个好主意有趣的-> ...
,因为它只是let s = ... in ...
的模糊版本。我建议写一些类似的东西(我不确定我完全理解你的代码,但你明白了......):If you want to remove consequent duplicates (the second option in the zeuxcg's solution), then you can also implement this directly as a recursive function (using accumulator parameter). This nicely demonstrates pattern matching, so it is good thing to try while learning F#:
This version works with lists, but since you're working with arrays, you'll probably need an imperative version. You can use sequence expressions like this:
As a side-note, I find your syntax a bit unreadable. I don't think it is a good idea to write
... |> fun s -> ...
, because it is just an obscured version oflet s = ... in ...
. I would recommend writing something like (I'm not sure I fully understand your code, but you get the idea...):使用循环而不是递归使用数组删除连续的重复项,最简单的是在如下序列表达式中:
Remove consecutive duplicates using arrays using loops rather than recursion, most simply in a sequence expression like this:
Seq.fold 是你的朋友。
这是基于 soundex 的维基百科文章。
Seq.fold is your friend.
This is based on the wikipedia article for soundex.
如果您想从数组中删除所有重复项(保留唯一元素),则可以执行以下操作:
如果您想删除连续的重复项,则解决方案会更困难。这是我能想到的最简单的一个:
您可以通过 Array.toList 和 Array.ofList 或使用 Array.fold 使用数组来完成此操作code> 并更改匹配表达式和列表构造;该代码的可读性较差,因此我发布了列表版本。
替代解决方案涉及 Seq.pairwise,即:
If you want to remove all duplicates from the array (leaving unique elements), the following will do:
If you want to remove consecutive duplicates, then the solution is harder. This is the simplest one I can come up with:
You can do it with arrays either via
Array.toList
andArray.ofList
or usingArray.fold
and changing match expression and list construction; the code is less readable so I'm posting the List version.Alternative solutions involve
Seq.pairwise
, i.e.: