2011-07-27 4 views
8

값을 목록의 n 번째 요소와 일치시키는 데 가장 적합한 스칼라 관용구는 무엇입니까?스칼라 목록의 n 번째 요소와 일치

분명히 순진 접근 방식은 작동하지 않습니다

scala> val list = List(5,6,7) 
list: List[Int] = List(5, 6, 7) 

scala> val x = 7 
x: Int = 7 

scala> x match { case list(2) => true; case _ => false } 
<console>:10: error: value list is not a case class constructor, nor does it have an  unapply/unapplySeq method 
    x match { case list(2) => true; case _ => false } 

이 질문이 목록의 n 번째 요소에 값을 비교하는 방법에 대해 아닙니다 clarify-하기 위해 - 그것을 할 수 있는지에 대해 구체적이다 일치를 사용하여 수행하십시오.

+4

시퀀스에 색인을 생성해야하는 경우 '목록'대신 '벡터'를 사용하는 것이 좋습니다. – missingfaktor

+1

사실,하지만 거의 모든 액세스가 머리에 맞으면 좀 더 자세히 살펴볼 필요가 거의 없으며 '목록'이 전체적으로 더 효율적일 수 있습니다. –

답변

17

보라, 예를 추출기의 힘을!

case class Nth[A](which: Int) { 
    def unapply(in: List[A]): Option[A] = if (in.size >= which+1) Some(in(which)) else None 
} 

val second = Nth[Int](1) 

List(2,4,6) match { 
    case second(4) => println("yep!") 
    case x => println("nope!") 
} 
+2

이것은 일회용으로는 너무 길긴하지만 훌륭한 추출기 예인 IMO입니다. 사용자 정의 추출기를 작성하지 않고도이를 수행 할 수있는 방법이있는 경우에만 가능합니다. –

+0

'in.size'는 O (n)입니다. 'Seq # lengthCompare '를 사용하는 것이 많은 경우에 더 빠르며 느려지지 않을 것입니다. –

1

직접적으로. 그러나 이들 중 하나가 할 수

x match { case _ if x == list(2) => true; case _ => false } 

또는

val listElem = list(2) 
x match { case `listElem` => true; case _ => false } 
+0

첫 번째 예는 가드 내부의 목록에서 n 번째 요소와 비교하는 것으로, 일종의 부정 행위입니다. 두 번째 것은 내가 찾고있는 것과 더 비슷합니다. 그 중 하나에 대한 유일한 추악한 점은 내가 일치하기 전에 n 번째 요소를 참조해야한다는 것입니다. –

3

당신이 목록과 일치 할 수합니다 (다음 stdlib에서 Regex 클래스가 유사하게 작동) :

def l(X : Int) = list match { 
    case _ :: _ :: X :: _ => true 
    case _ => false 
} 

scala> l(4) 
res13: Boolean = false 

scala> l(7) 
res14: Boolean = true 
2

글쎄, List는 이러한 추출기를 정의하지 않습니다,하지만 당신은 할 수 :

scala> class IndexOf[T](seq: Seq[T]) { 
    | def unapply(x: T) = seq find (x ==) map (seq indexOf _) 
    | } 
defined class IndexOf 

scala> val list = List(5,6,7) 
list: List[Int] = List(5, 6, 7) 

scala> val listndx = new IndexOf(list) 
listndx: IndexOf[Int] = [email protected] 

scala> val x = 7 
x: Int = 7 

scala> x match { case listndx(2) => true; case _ => false } 
res2: Boolean = true 

N 이것이 항상 첫 번째 일치를 반환합니다. 스칼라 패턴 매칭은 Prolog와 같이 작동하지 않습니다. 2을 공급하지 않으며 어쨌든 그것이 사실 일 수 있는지 확인하십시오.