Reputation: 253
So I have result: List[List[Int]] = (List(0,1), List(0,1), List(1))
and I want to get the numbers every element of the the list has in common (in this case 1) like a logical AND conjunction. How can I do that?
Edit: If an element is empty it should return an empty List because there are no values every element has in common
Upvotes: 1
Views: 374
Reputation: 385
The difficulty here is to do the intersect on the empty element, in this case Set.empty
. to avoid this and solve the problem more functionally we can do this
def uniqueElements(reults:List[List[Int]]):Set[Int] = {
results match {
case head1::head2::tail => head1.toSet intersect head2.toSet intersect uniqueElements(tail)
case head::Nil => head.toSet
case Nil => Set.empty[Int]
}
}
Upvotes: 1
Reputation: 9698
Intuitive way
In each sublist, filter out the elements that are contained in all sublists, then flatten and remove duplicated:
val result1 = list.flatMap(_.filter(e => list.forall(_.contains(e)))).toSet
More efficient way
Find the smallest sublist and pick out elements that are in each sublist:
val result2 = list.minBy(_.size).filter(e => list.forall(_.contains(e))).toSet
Mathematical way
Turn each sublist into a set and intersect them:
val result3 = list.map(_.toSet).reduce(_.intersect(_))
Upvotes: 2
Reputation: 2414
You can do it with the intersect
method:
def intersection(lists: List[List[Int]]): List[Int] = {
lists.headOption match {
case Some(head) =>
lists.foldLeft(head)((acc, l) => acc.intersect(l))
case None => Nil
}
The method may be more efficient if you use it with Set
instead of List
Upvotes: 1