我正在尝试创建一个程序,允许用户检查某个人是否有兴趣参加某个安排。我有类型
type InterestList = {
Interest : string;
}
type Description = {
Name : string;
Phone : int
BirthDate : int
Interests : list<InterestList>
}
type Register = {
RegID : list<Description>
}
type Arrangement = {
Year : int
ArrInterests : list<InterestList>
}
如果我然后使用一个包含所有我想检查的人的寄存器
let reg = [
("Steven", 11111111, 1991, (["Soccer", "Flowers", "Jazz"]))
("Carl", 22222222, 1842, (["Animals", "Shopping", "Soccer"]))
("Karen", 33333333, 2005, (["Animals", "Volleyball", "Jazz"]))
];;
有两种安排
let p1 =
[
(1982, (["Soccer", "Jazz"]))
];;
let p2 =
[
(1998, (["Soccer"]))
(1998, (["Jazz"]))
];;
如果一个人的年龄大于安排的年龄限制(因此,如果该人出生于 1982 年并且安排有 1987 年,则满足标准)并且如果利益该安排符合该人的全部或部分利益。 我想创建一个函数 extractInterested 以寄存器和排列作为参数。 有人吗?
编辑:
我已经尝试过类似的方法
let extractInterested f (person : Register list, arr : Arrangement list) =
if BirthYear > Year then
(person
|> List.map (fun x -> (x, List.tryFind (f x) arr))
|> List.iter (function (x, None) -> printfn "%A is not interested in going to the arrangement" x
| (x, Some y) -> printfn "%A is interested in going to the arrangement" x)
)
这应该在某种程度上比较两者(人的寄存器和排列),但是
if BirthYear > Year then
好像不行。
最佳答案
由于问题不是很具体,所以评论变得很困惑。我将尝试将其拆分为更明确定义的位。
第 1 步:什么数据结构适合给定的问题?
假设兴趣只是一个字符串,我们需要 person、register 和 arrangement 的类型。它与问题中的类型类似,但我不太清楚,所以让我们稍微修改一下:
type Person =
{ Name : string
PhoneNumber : int
BirthYear : int
Interests : Set<string> }
type Arrangement =
{ Year : int
CoveredInterests : Set<string> }
type Register =
{ People : Person list }
我使用集合来聚合兴趣,因为这不允许重复并通过集合交集简化共同兴趣的识别。
第 2 步:将人员与安排相匹配的算法应该是什么样的?
这里的主要功能是确定一个人是否感兴趣,所以像 isInterested
这样的功能可能是主要部分。 extractInterested
函数只是一个使用 isInterested
的过滤器。
let isInterested arrangement person =
let hasCommonInterest =
Set.intersect person.Interests arrangement.CoveredInterests
|> Set.isEmpty |> not
hasCommonInterest && person.BirthYear < arrangement.Year
let extractInterested register arrangement =
List.filter (isInterested arrangement) register.People
注意部分应用的使用:(isInterested arrangement)
是一个函数,回答特定的人是否对这个特定的排列感兴趣。
第 3 步:如何创建和使用实例?
这主要是 F# 记录和列表语法。
let steven =
{ Name = "Steven"; PhoneNumber = 11111111; BirthYear = 1991
Interests = set ["Soccer"; "Flowers"; "Jazz"] }
let carl =
{ Name = "Carl"; PhoneNumber = 22222222; BirthYear = 1842
Interests = set ["Animals"; "Shopping"; "Soccer"] }
let karen =
{ Name = "Karen"; PhoneNumber = 33333333; BirthYear = 2005
Interests = set ["Animals"; "Volleyball"; "Jazz"] }
let mainRegister = { People = [steven; carl; karen] }
let arrangement1 = { Year = 1982; CoveredInterests = set ["Soccer"; "Jazz"] }
使用 via extractInterested mainRegister arrangement1
将返回 Carl 的实例,该实例具有 Soccer 的共同兴趣,并且是唯一出生年份在 1982 年之前的人条目。
获取有用的 StackOverflow 答案的提示
问题越广泛,越难回答,因此将问题拆分成小的具体问题很有用。如果你让它抽象和小,你可能会发现它已经在某个地方得到了回答,而对于其余的情况,人们更有可能就最有问题的部分给你详细的建议。
解决这个问题可能会从这样的问题开始:“对于一组兴趣,我应该使用什么数据结构?”或“如何创建我创建的记录类型的实例?”。我建议首先使用文档或搜索来确定和回答此类问题,如果您遇到障碍,请询问有关您遇到的障碍的具体问题。
关于list - F# 创建用于比较包含列表的两个列表的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39637626/