Melkor
Melkor

Reputation: 253

Scala: AND conjunction in Lists

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

Answers (3)

Rachid Ait Abdesselam
Rachid Ait Abdesselam

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

slouc
slouc

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

vdebergue
vdebergue

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

Related Questions