Scala Получить первый и последний элементы списка с помощью сопоставления с образцом - PullRequest
11 голосов
/ 14 июля 2011

Я делаю сопоставление с образцом в списке.Можно ли в любом случае получить доступ к первому и последнему элементу списка для сравнения?

Я хочу сделать что-то вроде ..

case List(x, _*, y) if(x == y) => true

или

case x :: _* :: y =>

или что-то подобное ... где x иy - это первый и последний элементы списка ..

Как я могу это сделать ... любые идеи?

Ответы [ 4 ]

24 голосов
/ 14 июля 2011

Используйте стандартные : + и +: экстракторы из пакета 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)

16 голосов
/ 14 июля 2011

В случае, если вы пропустили очевидное:

case list @ (head :: tail) if head == list.last => true

Здесь есть часть head::tail, поэтому вы не можете найти ее в пустом списке.

9 голосов
/ 18 апреля 2017

просто:

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))
0 голосов
/ 27 июня 2019

Давайте разберемся с понятием, связанным с этим вопросом, между '::', '+:' и ': +':

есть разница

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

Ассоциативность оператора определяется последним символом оператора. Операторы, оканчивающиеся на двоеточие ‘:’, ассоциированы справа. Все остальные операторы левоассоциативны.

A левоассоциативная двоичная операция e1; op; e2 интерпретируется как e1.op (e2)

Если op ассоциативно справа , та же операция интерпретируется как {val x = e1; 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
...