Reputation: 33
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?
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.
Upvotes: 3
Views: 502
Reputation: 6223
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:
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
.
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.
Step 3: How are instances created and used?
This is mostly just F# record and list syntax.
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.
A hint for getting useful StackOverflow 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.
Upvotes: 4