Допускает ли Scala такой экстрактор?
Допустим, у меня есть эта коллекция:
val a = Array(Array(1,2,3,4,5),Array(4,5),Array(5),Array(1,2,6,7,8))
Есть ли способ определить экстрактор, который будет работать следующим образом:
a.foreach(e => {
e match {
case Array( ending with 5 ) =>
case _ =>
}
})
Извините за псевдокод, но я не знаю, как это выразить. Есть ли способ сопоставить что-то, имея 5 в качестве последнего элемента? Что если бы я захотел сопоставить что-то, имеющее 1 в качестве первого элемента и 5 в качестве последнего? Может ли это работать для массивов различной длины (обратите внимание, что я специально выбрал разные длины для своих массивов в примере).
Спасибо!
4 ответа
a.foreach(e => {
e match {
case a: Array[Int] if a.last == 5 =>
case _ =>
}
})
Вы можете сделать что-то немного лучше для сопоставления с первыми элементами:
a.foreach(e => {
e match {
case Array(1, _*) =>
case _ =>
}
})
К сожалению @_*
вещь должна быть последним элементом в списке аргументов массива. Но вы можете сделать сопоставление до этого настолько сложным, насколько захотите.
scala> val Array(1, x @_*) = Array(1,2,3,4,5)
x: Seq[Int] = Vector(2, 3, 4, 5)
scala> val Array(1, b, 3, x @_*) = Array(1,2,3,4,5)
b: Int = 2
x: Seq[Int] = Vector(4, 5)
Да, ты можешь:
object EndsWith {
def unapply[A]( xs: Array[A] ) =
if( xs.nonEmpty ) Some( xs.last ) else None
}
На вашем примере:
val a = Array(Array(1,2,3,4,5),Array(4,5),Array(5),Array(1,2,6,7,8))
a foreach {
case e @ EndsWith(5) => println( e.mkString("(",",",")" ) )
case _ =>
}
Печатает как положено (1,2,3,4,5)
, (4,5)
а также (5)
При таком же подходе вы можете написать экстрактор StartWith
и затем добавьте метод, чтобы объединить их в новом экстракторе, соответствующем обоим условиям.
case
поддерживает синтаксис if
с, так что это будет работать:
a foreach {
case a: Array[Int] if a.last == 5 =>
case _ =>
}
a.foreach (ar => ar.last match {
case 5 => println ("-> 5] " + ar.mkString ("~"))
case _ => println (" ?] " + ar.mkString (":")) })
Почему вы не подходите непосредственно для последнего элемента?
-> 5] 1~2~3~4~5
-> 5] 4~5
-> 5] 5
?] 1:2:6:7:8