2016-06-07 3 views
2

스칼라에서 두 개의 값이있는 목록과 일치하는 알고리즘을 작성하고 싶습니다. 예를 들어스칼라에서 두 개의 값을 가진 목록 일치

, 나는 다음과 같은 목록이있는 경우 :

val list = List(1, 3, 6, 8, 9, 14, 18) 

을 그리고이 두 값이 :

val result = List(6, 8, 9, 14) 

하는 경우가 있었다 :

val a = 4 

val b = 14 

나는이 목록을 얻으려면을 스칼라의 intersect 메쏘드 사용법에 대해 생각해 보았지만 두 목록에서만 작동합니다.

나는 또한 for주기를 사용한다고 생각했지만 기능적이지 않습니다.

그래서이 문제를 해결하는 방법에 대해서는 전혀 몰랐습니다.

아무도 도와 줄 수 있습니까?

+2

왜 필터 목록이 없습니까? 'list.filter (x => x> = 4 && x <= 14)' – Knight71

답변

6

아,하지만 사용 intersect는 :

scala> List(1, 3, 6, 8, 9, 14, 18) intersect (4 to 14) 
res1: List[Int] = List(6, 8, 9, 14) 

그리고 당신은 순서를 반대로 할 수 있지만, 결과 집합 유형이 다릅니다.

scala> 4 to 14 intersect List(1, 3, 6, 8, 9, 14, 18) 
res2: scala.collection.immutable.IndexedSeq[Int] = Vector(6, 8, 9, 14) 

테이크 아웃 : 스칼라 다른 콜렉션 유형을 많이 가지고 있지만, 그들 중 많은 사람들이 함께 잘 작동 않습니다.이해에 대한 사용

+0

두번째 예제 : 결과가'List' 일 필요가있는 경우 결과'Vector'에'toList'를 호출 할 수 있습니다. – Jesper

+0

귀하의 답변에 정말 도움이되었습니다. 하지만 캘린더 형식의 값이 있다고 가정 해 보겠습니다. 예를 들어 "2:30"과 같은 시간 인 경우입니다. 내가 볼 때 정수 값만 사용하기 때문에 "~"을 사용할 수 없습니다. 거기에 대한 functonal 해결 방법이 있습니까? –

+0

@ JoãoAlves, 도와 줘서 기쁩니다. 'Range' 콜렉션이 날짜/시간 값으로 사용될 수 없다는 것이 맞습니다. 이것은 다른 질문이며 입력 데이터 유형에 따라 대답이 달라질 것입니다. (문자열? java.util.Calendar?) 지금까지 시도한 것과 달성하려는 것에 대해 명확히하십시오. [BTW, 귀하의 질문에 가장 도움이되는 대답은 받아 들인 대답으로 표시되어야합니다.] – jwvh

1

는 다음과 같은 구문을 사용하여 목록을 지정할 수 있습니다 :

val list = List(1, 3, 6, 8, 9, 14, 18) 

그것은 당신을 위해 scala.collection.immutable.List을 만듭니다. 내가 제대로 작업을 이해한다면,이 oneliner이 문제 해결할 수 있습니다 :

list filter { element => a to b contains element } 

그래서 만약 == 4, 및 B == 14 당신은 얻을 것이다 : 재귀와

res0: List[Int] = List(6, 8, 9, 14) 
1

, 패턴 매칭 , 그리고 경비원. 흥미로운 부분은 보호자 if(h >= a && h <= b)입니다. 목록의 머리 부분이 ab 내에 있으면 선택됩니다. 그렇다면, 그것은 결과 목록에 선다.

def slice(a: Int, b: Int, xs: List[Int]): List[Int] = xs match { 
    case Nil       => Nil 
    case h::t if(h >= a && h <= b) => h :: slice(a,b,t) 
    case h::t      => slice(a,b,t) 
} 

테스트 :

scala> slice(4,14, list) 
res25: List[Int] = List(6, 8, 9, 14) 

scala> slice(18,20, list) 
res26: List[Int] = List(18) 

scala> slice(1,3, list) 
res27: List[Int] = List(1, 3) 

scala> slice(-2,0, list) 
res28: List[Int] = List() 

... 

꼬리 재귀 구현은 연습으로 떠났다. :) 그래서 같은

1

,

for (i <- xs if i >= 4 && i <= 14) yield i 

사용 편의성이 암시 클래스를 고려 들어 ,

implicit class OpsList(xs: List[Int]) { 
    def segment(a: Int, b:Int) = for (i <- xs if i >= a && i <= b) yield i 
} 

xs.segment(4,14) 
List(6, 8, 9, 14) 
0

Knight71의 댓글이 일반적으로 가장 간결, 효율적인 대답은 단지 이상으로 작동 할 수 있으며 잠재적이지 않습니다.

val result = list filter (x => x >= 4 && x <= 14) 

당신은 당신의 의도를 더 명확하게하는 함수를 만들 수 있습니다 :

def between(a: Int, b: Int)(x: Int): Boolean = x >= a && x <= b 

val result = list filter between(4, 14) 

이 버전은 정말 좋은 만민은 첫 번째 목록의 각 요소에 대해 전체 두 번째 목록을 검색 할 필요 당신이 서로 다른 많은 기준들을 묶어서 최종 결과를 도출한다면. 적용된 기준 목록을 구현 세부 사항과 구분합니다.

관련 문제