2017-12-31 12 views
0

저는 스칼라를 처음 접했고 컬렉션에서 패턴 매칭을 배우면서 마지막 요소 하나를 찾기 위해 일반적으로 간단한 로직을 작성했습니다. 내 첫 시도는 다음과 같습니다.스칼라 목록에서 끝에서 두 번째 요소 찾기

@scala.concurrent.tailrec 
def penultimate[A](elems: List[A]) = elems match { 
    case Nil => None 
    case first :: second :: Nil => Some(first) 
    case head :: tail => penultimate(tail) 
} 

이 방법으로 충분합니까? 꼬리 재귀에 대해 읽었고 내 메서드를 꼬리 재귀 적으로 만들었습니다!

그러나 다음과 같은 경우에 실패하고 내가 기대하는 곳 일부는 (1) :

penultimate[Int](List(1)) // This should give me Some(1) 

은 내가 할 수있는 것이 더 좋은 일이 있나요? 스칼라 컬렉션 라이브러리에서 reverse 메서드를 사용하여 이것을 하나의 라이너로 만들 수 있지만 사용하지 않으려 고했습니다.

더 좋은 방법이 있습니까?

+0

당신이 말하는 말이 정확하지 않습니다. 첫째, 코드가 컴파일되지 않습니다. 둘째 : 컴파일 오류를 고칠 때'두 번째 (List (1))'는'None'을 반환합니다. –

+0

혼란을 드려 죄송합니다. 나는 나의 포스트를 편집했다! –

+0

이제 혼란스러워합니다. 왜 당신은 '어떤 (1)'을 기대합니까? –

답변

1

2 가지 간단한 컴파일 오류를 해결하면 코드가 올바르게 작동하는 것 같습니다. 이 방법을 쓸 다른 방법은 :

def penultimate[A](elems: List[A]) = elems match { 
    case _ :+ elem :+ _ => Some(elem) 
    case elem +: Nil => Some(elem) // strange extra requirement 
    case _ => None 
} 

:+ (1) 전체의리스트하지만 마지막 요소, 및 (2)의 마지막 요소에 Seq를 해체. :: 또는보다 일반적인 +:과 비슷하지만 뒤에 있습니다. 나는 case init :+ elem :+ last을 쓸 수 있었지만 사용할 의도가없는 패턴 부분에 이름을 부여하지 않는 것을 선호합니다.

+0

첫 번째 사례가 어떻게 끝에서 두 번째 요소와 일치하는지 몇 가지 설명해 주시겠습니까? –

+0

몇 가지 설명을 추가했습니다. –

관련 문제