F#创建用于比较包含列表

时间:2016-09-22 11:21:10

标签: list f# compare

我正在尝试创建一个程序,允许用户检查某个人是否有兴趣进行某种安排。我有类型

    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 个答案:

答案 0 :(得分:4)

这是一个混乱的评论,因为这个问题并不具体。我会尝试将其拆分为更清晰的位。

第1步:对于给定问题,什么是合适的数据结构?

假设兴趣只是一个字符串,我们需要人,寄存和安排的类型。它与问题中的类型相似,但这些对我来说并不完全清楚,所以让我们稍微修改一下:

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答案的提示

问题越广泛,回答就越难,因此将问题分解成小的具体问题是有用的。如果你保持抽象和小,你可能会发现它已经在某个地方得到了解答,而对于其余的情况,人们更有可能就最有问题的部分给你详细的建议。

解决这个问题可能会从诸如&#34之类的问题开始;我应该将哪些数据结构用于一组兴趣?&#34;或&#34;如何创建我创建的记录类型的实例?&#34;。我建议您首先使用文档或搜索确定并回答此类问题,如果遇到障碍,请询问有关您遇到的障碍的具体问题。