Scala defines the contains method on all its collection classes.
Sets
Let’s say you have a set containing the nicknames of the guys in the band Rush, and you want to see whether a certain person is in the band. Just use contains:
val rush = Set("Dirk", "Lerxst", "Pratt")
val gotAlex = rush contains "Lerxst"
// gotAlex: Boolean = true
val gotAngus = rush contains "Angus"
// gotAngus: Boolean = false
Arrays, Lists, and Vectors (Oh, My!)
Seq and the sequence-like classes all define the contains method:
val rushSeq = Seq("Dirk", "Lerxst", "Pratt")
val rushA = Array("Dirk", "Lerxst", "Pratt")
val rushL = List("Dirk", "Lerxst", "Pratt")
val rushV = Vector("Dirk", "Lerxst", "Pratt")
val gotGene = rushSeq contains "Gene"
// gotGene: Boolean = false
val gotNeil = rushA contains "Pratt"
// gotNeil : Boolean = true
val gotAlex = rushL contains "Lerxst"
// gotAlex : Boolean = true
val gotPeter = rushV contains "Peter"
// gotPeter : Boolean = false
Sequences and the like also define a containsSlice method that takes a sequence and checks it is found in the collection. Order does matter, though:
val gotGedAndAl = rushSeq containsSlice Seq("Dirk", "Lerxst")
// gotGedAndAl: Boolean = true
// rushSeq has "Dirk" before "Lerxst", so the following fails
val gotAlAndGed = rushSeq containsSlice Seq("Lerxst", "Dirk")
// gotAlAndGed: Boolean = false
Strings
Because Scala just uses Java’s String class, we inherit the following from Java:
val gotX = "Lerxst" contains 'x' // gotX : Boolean = true val gotA = "Lerxst" contains 'A' // gotA : Boolean = false
Java overloads contains to accept a String as well as a char:
val gotXs = "Lerxst" contains "xs" // gotXs : Boolean = true val gotAb = "Lerxst" contains "Ab" // gotAb : Boolean = false
Because a String is also a sequence, Scala extends String with containsSlice if you prefer (perhaps for idiomatic reasons) to use it instead of contains. It can take a String or a sequence of Chars:
val gotXs = "Lerxst" containsSlice "xs"
// gotXs : Boolean = true
val gotXs = "Lerxst" containsSlice Seq('x', 's')
// gotXs : Boolean = true
Maps
Map has a contains method, and it operates on the Map‘s keys, not its values or its key-value pairs:
val rushM = Map( "Dirk" -> "bass", "Lerxst" -> "guitar", "Pratt" -> "drums") val gotGed = rushM contains "Dirk" // val gotGed : bool = true
To look among a Map‘s values, get the valuesIterator first. I’m not wild about this interface. It should have been values instead, but values returns an Iterable, which has no contains method:
val gotDrummer = rushM.valuesIterator contains "drums" // gotDrummer: Boolean = true val gotSitarist = rushM.valuesIterator contains "sitar" // gotSitarist: Boolean = false
There is no contains variant that searches on a key-value pair. You can define an extension method containsPair:
object MapExt {
implicit class RichMap[A,B](val m: Map[A,B]) extends AnyVal {
def containsPair(p: (A,B)): Boolean =
m get p._1 contains p._2
}
}
import MapExt._
val gotGedOnBass = rushM containsPair ("Dirk" -> "bass")
// gotGedOnBass: Boolean = true
val gotGedOnFlute = rushM containsPair ("Dirk" -> "flute")
// gotGedOnFlute: Boolean = false
val gotGeorgeOnSitar = rushM containsPair ("George" -> "sitar")
// gotGeorgeOnSitar: Boolean = false