Anthony
Anthony

Reputation: 35988

How to find a string in a list of case class

I have a case class Color

scala> case class Color(code: String, qty: String, shadecode: String, foo: Int)

I have a list of case class

scala> val c = List[Color](Color("100", "10", "99"), Color("200", "20", "88"), Color("300", "10", "99"))

How can I determine whether this string is present in the list:

scala> val colorString = "1001099"

The convention of the string will always be the same. First three characters will be code, next two will be qty, and last two will be shadecode

I've tried the following but it doesn't work since I am not passing any value for foo:

def doesExist(s: String, colors: Color): Boolean = {
  return colors.exists(_==Color(code= s.substring(0,3), qty = s.substring(3,4), shadecode = s.substring(5,6)))
}

Upvotes: 0

Views: 287

Answers (4)

gekomad
gekomad

Reputation: 565

You should create the key early so the search is faster

case class Color(code: String, qty: String, shadecode: String) {
  val k = s"$code$qty$shadecode"
}
val c = List[Color](Color("100", "10", "99"), Color("200", "20", "88"), Color("300", "10", "99"))
c.filter(_.k == "1001099") // Color(100,10,99)
c.exists(_.k == "1001099") // true    

Upvotes: 1

Tarang Bhalodia
Tarang Bhalodia

Reputation: 1195

Add a function inside your case class and use that function to check if the string is a match. Here's the simple solution:

case class Color(code: String, qty: String, shadecode: String, foo: Int) {
  def matchString(colorString: String): Boolean = {
    val (code, qty, shadecode) = (
      colorString.substring(0,3),
      colorString.substring(3,5),
      colorString.substring(5,7))

    this.code == code && this.qty == qty && this.shadecode == shadecode
  }
}

And then:

 val exists = YOUR_COLOR_LIST.exists(_.matchString(YOUR_STRING))

Upvotes: 1

Thilo
Thilo

Reputation: 262734

How about

def findColor(s: String, colors: Seq[Color]): Option[Color] = {
   val (code, qty, shadecode) = (
     s.substring(0,3), 
     s.substring(3,5), 
     s.substring(5,7))
   colors.find(c => c.code == code && c.qty == qty && c.shadecode == shadecode)
}

val exists = findColor("1001099", colors).isDefined

If the list of colors is large and static (meaning you search in the same list all over again many times), you may also want to build an index instead (to get this from O(n) to O(1) --- but only if you can reuse the index a lot).

val indexedColors: Map[String, Color] = colors.map(c => (c.toCodeString, c)).toMap
val exists = indexColors.containsKey("1001099")

Upvotes: 0

anuj saxena
anuj saxena

Reputation: 279

You can reframe your function using deep matching functionality of case classes:

def doesExist(s: String, colors: List[Color]): Boolean = {
  val (code, qty, shadecode) = (s.substring(0,3), s.substring(3,5), s.substring(5,7))
  colors.exists{
    case Color(`code`, `qty`, `shadecode`, _) => true
    case _ => false
  }
}

And also, the parameters you were providing to substring method for qty and shadecode were incorrect.

Upvotes: 0

Related Questions