복붙노트

[SCALA] 서열 목록 이외의 스칼라 패턴 매칭

SCALA

서열 목록 이외의 스칼라 패턴 매칭

나는 재귀 목록 내 각 요소에 대해 작동하는 다음 코드가

def doMatch(list: List[Int]): Unit = list match {
  case last :: Nil  => println("Final element.")
  case head :: tail => println("Recursing..."); doMatch(tail)
}

이제)이 기능은 필터 ()와 foreach는 (통해 사용할 수 있음을 무시하고, 이것은 잘 작동합니다. 내가 어떤 서열 [지능] 동의로 변경하려고한다면, 나는 문제에 실행 :

여기가 작동하지 않습니다 제외하고 내가, 코드가 보일 것입니다 생각하는 방법이다 :

def doMatch(seq: Seq[Int]): Unit = seq match {
  case last +: Seq() => println("Final element.")
  case head +: tail  => println("Recursing..."); doMatch(tail)
}

편집 : 그래서 많은 좋은 답변! 자신의 내 예제에서 작업자하지만,이 경우 클래스 따라서 차이가 아니라고 :: 언급하는 처음으로 나는 agilesteel의 답변을 받아들이는거야.

해결법

  1. ==============================

    1.스칼라에서 두 :: (발음 단점)이있다. 한 클래스 정의리스트 연산자이고 하나는 머리와 꼬리를 특징으로하는 비 빈 목록을 나타내는 클래스 (목록의 서브 클래스)이다.

    스칼라에서 두 :: (발음 단점)이있다. 한 클래스 정의리스트 연산자이고 하나는 머리와 꼬리를 특징으로하는 비 빈 목록을 나타내는 클래스 (목록의 서브 클래스)이다.

    :( 머리, 꼬리) : 머리 :: 꼬리는 구문에서 수정 된 생성자 패턴입니다.

    :: 그것을 위해 정의 된 객체 추출기가 의미 경우 클래스이다.

  2. ==============================

    2.부정 행위의 종류,하지만 여기 간다 :

    부정 행위의 종류,하지만 여기 간다 :

    def doMatch(seq: Seq[Int]): Unit = seq match {
      case Seq(x) => println("Final element " + x)
      case Seq(x, xs@_*) => println("Recursing..." + x); doMatch(xs)
    }
    

    XS *이 작동하지 않는 이유를 묻지 마세요 ...

  3. ==============================

    3.2012 년 3 월 십오로,이 2.10+에서 작동 :

    2012 년 3 월 십오로,이 2.10+에서 작동 :

      def doMatch(seq: Seq[Int]): Unit = seq match {
        case last +: Seq() => println("Final element.")
        case head +: tail  => println("Recursing..."); doMatch(tail)
      }                                               //> doMatch: (seq: Seq[Int])Unit
    
      doMatch(List(1, 2))                             //> Recursing...
                                                      //| Final element.
    

    더 일반적으로, 두 개의 서로 다른 헤드 / 테일 및 초기화 / 마지막 분해는 객체 미러링 APPEND / 앞에 추가 SeqExtractors에 서열에 대한 추가되었습니다

    List(1, 2) match { case init :+ last => last } //> res0: Int = 2                                              
    List(1, 2) match { case head +: tail => tail } //> res1: List[Int] = List(2)                                               
    Vector(1, 2) match { case init :+ last => last } //> res2: Int = 2                                              
    Vector(1, 2) match { case head +: tail => tail } //> res3: scala.collection.immutable.Vector[Int] = Vector(2)
    
  4. ==============================

    4.당신은 실제로 +에 대한 객체를 정의 할 수 있습니다 : 당신이 찾고있는 정확하게 할 :

    당신은 실제로 +에 대한 객체를 정의 할 수 있습니다 : 당신이 찾고있는 정확하게 할 :

    object +: { 
      def unapply[T](s: Seq[T]) = 
        if(s.nonEmpty)
          Some(s.head, s.tail) 
        else
          None
    }
    
    scala> val h +: t = Seq(1,2,3)
    h: Int = 1
    t: Seq[Int] = List(2, 3)
    

    그런 다음 코드는 정확히 예상대로 작동합니다.

    이 작동하기 때문에 H + : t는 + :( 뜨거운) 패턴 매칭을 사용하는 것과 같다.

  5. ==============================

    5.나는 표준 라이브러리의 임의의 시퀀스 패턴 매칭 지원이 있다고 생각하지 않습니다. 당신은 밖으로 패턴 매칭하지만 함께 할 수있다 :

    나는 표준 라이브러리의 임의의 시퀀스 패턴 매칭 지원이 있다고 생각하지 않습니다. 당신은 밖으로 패턴 매칭하지만 함께 할 수있다 :

      def doMatch(seq: Seq[Int]) {
        if (seq.size == 1) println("final element " + seq(0)) else {
          println("recursing")
          doMatch(seq.tail)
        }
      }
      doMatch(1 to 10)
    

    당신은 당신의 자신의 추출 객체 생각을 정의 할 수 있습니다. http://www.scala-lang.org/node/112 참조

    object SEQ {
      def unapply[A](s:Seq[A]):Option[(A, Seq[A])] = {
        if (s.size == 0) None else {
          Some((s.head, s.tail))
        }
      }
    }
    
    def doMatch(seq: Seq[Int]) {
      seq match {
        case SEQ(head, Seq()) => println("final")
        case SEQ(head, tail) => {
          println("recursing")
          doMatch(tail)
        }
      }
    }
    
  6. ==============================

    6.목록에 서열에서 간단한 변환은 일을 할 것입니다 :

    목록에 서열에서 간단한 변환은 일을 할 것입니다 :

    def doMatch (list: List[Int]): Unit = list match {           
        case last :: Nil => println ("Final element.")             
        case head :: tail => println ("Recursing..."); doMatch (tail)
        case Nil => println ("only seen for empty lists") 
      }
    
    def doMatchSeq (seq: Seq[Int]) : Unit = doMatch (seq.toList)
    
    doMatch (List(3, 4, 5))
    doMatchSeq (3 to 5)
    
  7. from https://stackoverflow.com/questions/6807540/scala-pattern-matching-on-sequences-other-than-lists by cc-by-sa and MIT license