f#创建函数,用于比较两个列表的列表。

时间:2021-03-09 22:50:13

I'm trying to create a program that allows the user to check if a certain person will be interested in going to a certain arrangement. I have the types

我正在尝试创建一个程序,允许用户检查某个特定的人是否对某种安排感兴趣。我的类型

    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>
    }

If I then use a register containing all the people I'd like to check

如果我使用一个寄存器包含所有我想要检查的人。

  let reg = [
     ("Steven", 11111111, 1991, (["Soccer", "Flowers", "Jazz"]))
     ("Carl", 22222222, 1842, (["Animals", "Shopping", "Soccer"]))
     ("Karen", 33333333, 2005, (["Animals", "Volleyball", "Jazz"]))
  ];;

and have two arrangements

和有两个安排

       let p1 = 
       [
         (1982, (["Soccer", "Jazz"]))
       ];;

       let p2 = 
       [
         (1998, (["Soccer"]))
         (1998, (["Jazz"]))
       ];;

A person will be interested in going to the arrangement if his age is greater than the age restraint on the arrangement (so if the person is born in 1982 and the arrangement has 1987, the criteria is fulfilled) and if the interests of the arrangement matches all or some of the interests of the person. I'd like to create a function extractInterested taking a register and an arrangement as arguments. Anyone?

要安排一个人会感兴趣如果他的年龄大于年龄限制安排(如果这个人是生于1982年,有1987的安排,完成标准)的利益,如果安排比赛全部或部分人的利益。我想要创建一个函数提取,将寄存器和一个排列作为参数。有人知道吗?

EDIT:

编辑:

I've tried something along the lines of

我试过一些类似的方法。

       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)
                     )

This should to some extent compare the two (the register of people and the arrangement), but the

这应该在一定程度上比较两者(人的登记和安排),但是。

      if BirthYear > Year then

doesn't seem to work.

似乎没有工作。

1 个解决方案

#1


4  

This is getting confused comments because the question isn't very specific. I'll try to split it into more sharply defined bits.

因为这个问题不是很具体,所以会有一些混乱的评论。我会试着把它分成更明确的部分。

Step 1: What could be a suitable data structure for the given problem?

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

Assuming that an interest is merely a string, we need types for person, register, and arrangement. It'll be similar to the types in the question, but those aren't completely clear to me, so let's modify them a bit:

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

I use sets for aggregating interests, since this disallows duplicates and simplifies identification of common interests via set intersection.

我使用集合来聚合兴趣,因为这个不允许重复,并且通过设置交集简化了共同兴趣的识别。

Step 2: What should the algorithm to match people with arrangements look like?

第二步:该算法应该如何匹配人们的安排?

The main functionality here is to determine whether a person is interested or not, so a function like isInterested could be the main bit. The extractInterested function is then just a filter that makes use of isInterested.

这里的主要功能是确定一个人是否感兴趣,所以像isInterested这样的函数可能是主要的部分。然后,提取兴趣的函数就是一个利用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

Note the use of partial application: (isInterested arrangement) is a function that answers whether a specific person is interested in this specific arrangement.

注意,部分应用程序的使用:(isInterested安排)是一个函数,它回答特定的人是否对这个特定的安排感兴趣。

Step 3: How are instances created and used?

步骤3:如何创建和使用实例?

This is mostly just F# record and list syntax.

这主要是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"] }

Using via extractInterested mainRegister arrangement1 will return Carl's instance, which has the common interest of Soccer and is the only person entry with a birth year before 1982.

使用通过提取感兴趣的mainRegister安排将会返回卡尔的实例,该实例具有足球的共同兴趣,并且是1982年之前唯一一个出生年份的人。

A hint for getting useful * answers

提示获取有用的*答案。

The broader a question is, the harder it is to answer, so it's useful to split problems up into small, specific questions. If you keep it abstract and small, you'll probably find it already answered somewhere, and for the remaining cases, people are more likely to give you detailed advice about the most problematic part.

问题越宽泛,回答的难度就越大,所以把问题分成小的、具体的问题是很有用的。如果你保持它的抽象和小,你可能会发现它已经在某个地方找到了答案,而对于剩下的案例,人们更有可能给你详细的建议关于最有问题的部分。

Solving this problem might begin with questions like "What data structure should I use for a set of interests?" or "How do I create instances of a record type I created?". I'd recommend to first determine and answer such questions using documentation or search, and if you hit a roadblock, ask a specific question about the obstacle you're struggling with.

解决这个问题可能会从诸如“我应该用什么数据结构来获取一组兴趣”之类的问题开始,或者“我如何创建我创建的记录类型的实例?”我建议你先用文档或搜索来确定和回答这些问题,如果你遇到了障碍,问一个关于你正在努力克服的障碍的具体问题。

#1


4  

This is getting confused comments because the question isn't very specific. I'll try to split it into more sharply defined bits.

因为这个问题不是很具体,所以会有一些混乱的评论。我会试着把它分成更明确的部分。

Step 1: What could be a suitable data structure for the given problem?

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

Assuming that an interest is merely a string, we need types for person, register, and arrangement. It'll be similar to the types in the question, but those aren't completely clear to me, so let's modify them a bit:

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

I use sets for aggregating interests, since this disallows duplicates and simplifies identification of common interests via set intersection.

我使用集合来聚合兴趣,因为这个不允许重复,并且通过设置交集简化了共同兴趣的识别。

Step 2: What should the algorithm to match people with arrangements look like?

第二步:该算法应该如何匹配人们的安排?

The main functionality here is to determine whether a person is interested or not, so a function like isInterested could be the main bit. The extractInterested function is then just a filter that makes use of isInterested.

这里的主要功能是确定一个人是否感兴趣,所以像isInterested这样的函数可能是主要的部分。然后,提取兴趣的函数就是一个利用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

Note the use of partial application: (isInterested arrangement) is a function that answers whether a specific person is interested in this specific arrangement.

注意,部分应用程序的使用:(isInterested安排)是一个函数,它回答特定的人是否对这个特定的安排感兴趣。

Step 3: How are instances created and used?

步骤3:如何创建和使用实例?

This is mostly just F# record and list syntax.

这主要是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"] }

Using via extractInterested mainRegister arrangement1 will return Carl's instance, which has the common interest of Soccer and is the only person entry with a birth year before 1982.

使用通过提取感兴趣的mainRegister安排将会返回卡尔的实例,该实例具有足球的共同兴趣,并且是1982年之前唯一一个出生年份的人。

A hint for getting useful * answers

提示获取有用的*答案。

The broader a question is, the harder it is to answer, so it's useful to split problems up into small, specific questions. If you keep it abstract and small, you'll probably find it already answered somewhere, and for the remaining cases, people are more likely to give you detailed advice about the most problematic part.

问题越宽泛,回答的难度就越大,所以把问题分成小的、具体的问题是很有用的。如果你保持它的抽象和小,你可能会发现它已经在某个地方找到了答案,而对于剩下的案例,人们更有可能给你详细的建议关于最有问题的部分。

Solving this problem might begin with questions like "What data structure should I use for a set of interests?" or "How do I create instances of a record type I created?". I'd recommend to first determine and answer such questions using documentation or search, and if you hit a roadblock, ask a specific question about the obstacle you're struggling with.

解决这个问题可能会从诸如“我应该用什么数据结构来获取一组兴趣”之类的问题开始,或者“我如何创建我创建的记录类型的实例?”我建议你先用文档或搜索来确定和回答这些问题,如果你遇到了障碍,问一个关于你正在努力克服的障碍的具体问题。