list - F# 创建用于比较包含列表的两个列表的函数

标签 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 步:什么数据结构适合给定的问题?

假设兴趣只是一个字符串,我们需要 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/

相关文章:

list - 不允许玩家移出2D网格Python 3之外

r - 仅选择包含 R 中两列表的列表的元素

visual-studio - 在f#和C#项目之间导航

f# - 在 f# 程序中查找死代码

java - 比较运算符自定义对象java

java - 在列表/ HashMap 中分组数据

c++ - 根据条件拆分 STL 列表

f# - F#中的代码分析

r - 如何比较唯一值的数量

java - 比较 2 个二维数组 - Java