Scala Get First and Last elements of List using Pattern Matching

后端 未结 4 933
故里飘歌
故里飘歌 2020-12-16 00:02

I am doing a pattern matching on a list. Is there anyway I can access the first and last element of the list to compare?

I want to do something like..



        
相关标签:
4条回答
  • 2020-12-16 00:41

    In case you missed the obvious:

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

    The head::tail part is there so you don’t match on the empty list.

    0 讨论(0)
  • 2020-12-16 00:46

    Lets understand the concept related to this question, there is a difference between '::', '+:' and ':+':

    1st Operator:

    '::' - It is right associative operator which works specially for lists

    scala> val a :: b :: c = List(1,2,3,4)
    a: Int = 1
    b: Int = 2
    c: List[Int] = List(3, 4)
    

    2nd Operator:

    '+:' - It is also right associative operator but it works on seq which is more general than just list.

    scala> val a +: b +: c = List(1,2,3,4)
    a: Int = 1
    b: Int = 2
    c: List[Int] = List(3, 4)
    

    3rd Operator:

    ':+' - It is also left associative operator but it works on seq which is more general than just list

    scala> val a :+ b :+ c = List(1,2,3,4)
    a: List[Int] = List(1, 2)
    b: Int = 3
    c: Int = 4
    

    The associativity of an operator is determined by the operator’s last character. Operators ending in a colon ‘:’ are right-associative. All other operators are left-associative.

    A left-associative binary operation e1;op;e2 is interpreted as e1.op(e2)

    If op is right-associative, the same operation is interpreted as { val x=e1; e2.op(x) }, where x is a fresh name.

    Now comes answer for your question: So now if you need to get first and last element from the list, please use following code

    scala> val firstElement +: b :+ lastElement = List(1,2,3,4)
    firstElement: Int = 1
    b: List[Int] = List(2, 3)
    lastElement: Int = 4
    
    0 讨论(0)
  • 2020-12-16 00:54

    Use the standard :+ and +: extractors from the scala.collection package


    ORIGINAL ANSWER

    Define a custom extractor object.

    object :+ {
      def unapply[A](l: List[A]): Option[(List[A], A)] = {
        if(l.isEmpty)
          None
        else 
          Some(l.init, l.last)
      }
    }
    

    Can be used as:

    val first :: (l :+ last) = List(3, 89, 11, 29, 90)
    println(first + " " + l + " " + last) // prints 3 List(89, 11, 29) 90
    

    (For your case: case x :: (_ :+ y) if(x == y) => true)

    0 讨论(0)
  • 2020-12-16 01:00

    simply:

    case head +: _ :+ last => 
    

    for example:

    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 讨论(0)
提交回复
热议问题