There is a guest coming for lunch and at each table there is one person (bob, peter, simon or sarah) and on that table there is one fruit bowl.
I need to score the matches of fruit in order to decide which person/table the guest should with/at.
My thinking is that I need to give each person a score based on the amount of matches they have with the guests fruit. So I need to compare a List[Fruit]
with a List[Fruit]
then return the Person
I need to return a Map as per below
case class Person(str: String, value: List[Fruit])
case class Fruit(fruit: String)
val guest: Person = Person("Unknown", List(Fruit("Apple"), Fruit("Pear"), Fruit("Grapes")))
val bob: Person = Person("Bob", List(Fruit("Apple"), Fruit("Pear"), Fruit("Grapes"))) // 3
val peter: Person = Person("Peter", List(Fruit("Apple"), Fruit("Pineapple"), Fruit("Mango"))) // 1
val simon: Person = Person("Simon", List(Fruit("Apple"), Fruit("Pear"), Fruit("Mango"))) // 2
val sarah: Person = Person("sarah", List(Fruit("Pear"), Fruit("Grapes"), Fruit("Mango"))) // 2
Map( 3 ->
Person("Bob", List(Fruit("Apple"), Fruit("Pear"), Fruit("Grapes"))),
2 -> Person("Simon", List(Fruit("Apple"), Fruit("Pear"), Fruit("Mango"))),
2 -> Person("sarah", List(Fruit("Pear"), Fruit("Grapes"), Fruit("Mango"))),
1 -> Person("Peter", List(Fruit("Apple"), Fruit("Pineapple"), Fruit("Mango")))
)
CodePudding user response:
Although the other answer should work, but it is kind of like imperative approach, and personally I wouldn't use mutation as far as possible, I would recommend using the intersection of fruits set in order to find the fruits in common:
val persons = List(bob, peter, simon, sarah)
persons.map { person =>
val fruitsInCommon = (person.value.toSet & guest.value.toSet).size
fruitsInCommon -> person
}.sortBy(_._1).toMap
You can also use .view
on the persons if you'd like to.
CodePudding user response:
This will give a map that groups people by number of fruit they have in common with the guest:
val persons = List(bob, peter, simon, sarah)
persons.groupMap(_.value.intersect(guest.value).size)(_.str)
// Map(1 -> List(Peter), 2 -> List(Simon, sarah), 3 -> List(Bob))
Using Set
would be more efficient, perhaps as a calculated value on Person
:
case class Person(str: String, value: List[Fruit]) {
lazy val fruitSet = value.toSet
}
persons.groupMap(_.fruitSet.intersect(guest.fruitSet).size)(_.str)