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 Char
s:
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