Scala Получить первый и последний элементы списка с использованием сопоставления с образцом
Я делаю сопоставление шаблонов в списке. Есть ли в любом случае доступ к первому и последнему элементам списка для сравнения?
Я хочу сделать что-то вроде..
case List(x, _*, y) if(x == y) => true
или
case x :: _* :: y =>
или что-то подобное...
где x
и y
- это первый и последний элементы списка.
Как я могу это сделать... любые идеи?
Ответы
Ответ 1
Используйте стандартные : + и +: экстракторы из пакета scala.collection
ОРИГИНАЛЬНЫЙ ОТВЕТ
Определите пользовательский объект-экстрактор.
object :+ {
def unapply[A](l: List[A]): Option[(List[A], A)] = {
if(l.isEmpty)
None
else
Some(l.init, l.last)
}
}
Может использоваться как:
val first :: (l :+ last) = List(3, 89, 11, 29, 90)
println(first + " " + l + " " + last) // prints 3 List(89, 11, 29) 90
(Для вашего случая: case x :: (_ :+ y) if(x == y) => true
)
Ответ 2
Если вы пропустили очевидное:
case list @ (head :: tail) if head == list.last => true
Здесь находится часть head::tail
, поэтому вы не соглашаетесь на пустой список.
Ответ 3
просто:
case head +: _ :+ last =>
например:
scala> val items = Seq("ham", "spam", "eggs")
items: Seq[String] = List(ham, spam, eggs)
scala> items match {
| case head +: _ :+ last => Some((head, last))
| case List(head) => Some((head, head))
| case _ => None
| }
res0: Option[(String, String)] = Some((ham,eggs))
Ответ 4
Давайте разберемся с концепцией, связанной с этим вопросом, между '::', '+:' и ': +' есть разница:
1-й оператор:
' :: ' - это правильный ассоциативный оператор, который работает специально для списков
scala> val a :: b :: c = List(1,2,3,4)
a: Int = 1
b: Int = 2
c: List[Int] = List(3, 4)
2-й оператор:
' +: ' - это также правильный ассоциативный оператор, но он работает на seq, который является более общим, чем просто список.
scala> val a +: b +: c = List(1,2,3,4)
a: Int = 1
b: Int = 2
c: List[Int] = List(3, 4)
3-й оператор:
' : + ' - это также левый ассоциативный оператор, но он работает на seq, который является более общим, чем просто список
scala> val a :+ b :+ c = List(1,2,3,4)
a: List[Int] = List(1, 2)
b: Int = 3
c: Int = 4
Ассоциативность оператора определяется оператором последнего символа. Операторы, оканчивающиеся на двоеточие: ассоциативны справа. Все остальные операторы левоассоциативны.
Левый-ассоциативная бинарная операция е1; оп; е2 интерпретируется как e1.op (е2)
Если op является ассоциативным справа, эта же операция интерпретируется как {val x = e1; e2.op(x) }, where x is a fresh name. e2.op(x)}, где x - новое имя.
Теперь приходит ответ на ваш вопрос: так что теперь, если вам нужно получить первый и последний элемент из списка, пожалуйста, используйте следующий код
scala> val firstElement +: b :+ lastElement = List(1,2,3,4)
firstElement: Int = 1
b: List[Int] = List(2, 3)
lastElement: Int = 4