list - F# List split,divide
问题描述
我正在尝试在 F# 中解决一个练习。我必须编写一个可以区分书和电影的代码,并将其作为书或电影放在列表中。它可以通过文件大小区分两者,因为书籍没有文件大小。例如,如果我放入一本书,代码必须将它作为一本书添加到列表中,并且对于电影也是如此。我将示例结果和输入链接起来。先感谢您。
type Movie =
{ movieName: string
duration: Nat
fileSize: Nat }
type Book =
{ bookName: string
pages: Nat }
type Activity =
| Watch of Movie
| Read of Book
let rec createActivities(hl: (string * Nat * Nat) list): Activity list =
match hl with
| [] -> []
| x::xs -> ....
以下是输入:
createActivities([
"The Hobbit" , 304N, 0N
"The Fellowship of the Ring", 228N, 50N
"The Name of the Wind" , 662N, 0N
"The Emoji Movie" , 86N , 1024N
"The Hobbit" , 164N, 9001N
"The Fellowship of the Ring", 700N, 0N
结果:
[
Read { bookName = "The Hobbit"; pages = 304N }
Watch { movieName = "The Fellowship of the Ring"; duration = 228N; fileSize = 50N }
Read { bookName = "The Name of the Wind"; pages = 662N }
Watch { movieName = "The Emoji Movie"; duration = 86N; fileSize = 1024N }
Watch { movieName = "The Hobbit"; duration = 164N; fileSize = 9001N }
Read { bookName = "The Fellowship of the Ring"; pages = 700N }
]
解决方案
F# 中的匹配表达式可以非常先进,在匹配表达式的各个部分中都有子匹配。例如,x::xs
匹配表达式中的大小写可以转换为(name, duration, filesize) :: xs
. 如果您为其中一个指定一个值,那么它只会在元组的该部分具有该值时匹配。考虑到这一点,我会将你的匹配表达式写成这样:
let rec createActivities(hl: (string * Nat * Nat) list): Activity list =
match hl with
| [] -> []
| (name, pages, 0N) :: xs -> Read { bookName = name; pages = pages } :: createActivities xs
| (name, duration, fileSize) :: xs -> Watch { movieName = name; duration = duration; fileSize = fileSize } :: createActivities xs
其工作原理是,match
将按从上到下的顺序处理案例,并使用第一个匹配的案例。所以如果元组作为0N
它的第三个元素,将使用第二个匹配情况,否则将使用第三个匹配情况。所以匹配表达式可以保持非常简单和干净。
推荐阅读
- vba - 如何将所有选定的邮件及其类别和接收时间保存到一个文件夹中?
- r - 文件不存在时如何退出downloadHandler
- java - 如何用更快的东西替换 SortedSet 或加快速度
- java - 如何使用 split() 删除路径中的最后一个目的地?
- python - 如何在 excel 中打开 csv 并一步应用条件格式?
- javafx - 检测在哪个(两个)tableview 上发生了双击
- python - 仅更正数组上的一个(具体)位置 - Python
- vis.js - vis.js 时间线在项目上设置自定义背景颜色而不覆盖边框
- c# - 第二次迁移时出现 Entity Framework Core 编译器错误
- c# - 初始化全局存储库或表单?