undisp
undisp

Reputation: 721

Scala: filter multiple elements of a list

Assuming I have these scala classes:

Task(id: String, pr: List[PhysicalResource])

PhysicalResource(id: String)

A list: List[PhysicalResource] with these elements:

("PR1" :: "PR2" :: "PR3" :: "PR4" :: Nil)

And this obj: Task object:

("T1", List(PhysicalResource("PR1"), PhysicalResource("PR3")))

I want to return the first two elements (two, because obj.physicalResources.size = 2) of list that match the Physical Resources of the object.

In this example I want to return:

("PR1" :: "PR3" :: Nil)

I am doing this, but it doesn't return anything:

list.filter{x => obj.physicalResources.contains(x)}

Does anyone know how can I do this?

Upvotes: 0

Views: 2944

Answers (3)

Leo C
Leo C

Reputation: 22449

If I understand your question correctly, you're trying to match obj's PhysicalResource ids against the master list. List of PhysicalResource ids in obj is obj.pr.map(_.id), hence you can use intersect between the two lists to get the matching ids as follows:

case class PhysicalResource(id: String)
case class Task(id: String, pr: List[PhysicalResource])

val list: List[String] = "PR1" :: "PR2" :: "PR3" :: "PR4" :: Nil

val obj: Task = Task("T1", List(PhysicalResource("PR1"), PhysicalResource("PR3")))

list.intersect(obj.pr.map(_.id))
res1: List[String] = List(PR1, PR3)

Upvotes: 0

Carcigenicate
Carcigenicate

Reputation: 45836

I can't reproduce your issue using filter:

val resources: List[String] =
 ("PR1" :: "PR2" :: "PR3" :: "PR4" :: Nil)

// Representing obj.physicalResources
val physicalResources: List[String] =
 ("PR1" :: "Something Else" :: "PR3" :: Nil)

val filtered: List[String] =
  resources.filter{x => physicalResources.contains(x)}

println(filtered)

// Prints List(PR1, PR3)

But try this way that uses intersect:

// Take the intersection of the 2 lists; the parts that are the same
println(resources.intersect(physicalResources))

// Prints List(PR1, PR3)

Rolling your own method to accomplish this seems a little excessive.

Upvotes: 2

DeusEx
DeusEx

Reputation: 147

I recently came up with a generic solution for a similar problem:

def hasSubsequence[A](sup: List[A], sub: List[A]): Boolean = {
  def hasSubsequenceR[A](sup1: List[A], sub1: List[A]): Boolean = sup1 match {
    case x :: xs => sub1 match {
      case y :: ys if x == y => hasSubsequenceR(xs, ys)
      case Nil => true
      case _ => hasSubsequenceR(xs, sub)
   }
   case _ => false
 }
 hasSubsequenceR(sup, sub)
}

where sup is your list and sub is your obj.pr

Hope this helps

Upvotes: 0

Related Questions