2015-01-12 2 views
1

기능 방식이 중첩에 대한 루프를 조정할 수있는 가이드가 필요 :내가이 스칼라 코드에서 일하고 있어요

case class M(a: String, b: Int) 

    val mm1 = List(Map("a" -> "001", "b" -> 12), Map("a" -> "002", "b" -> 25), Map("a" -> "003", "b" -> 100)) 
    val mm2 = List(M("001", 12), M("004", 99), M("003", 100)) 

    def validate(mm1: List[Map[String, Any]], mm2: List[M]): Boolean = { 

    for (m1 <- mm1) { 
     var found = false 
     val a = m1("a") 

     // nested loop: iterate mm2 
     breakable { 
     for (m2 <- mm2) { 
      if (a == m2.a) { 
      assert(m1("b") == m2.b) 
      found = true 
      break // if found just break 
      } 
     } 
     } 

     // All of elements in mm1 must exist in mm2. 
     // We will know this if "found" variable is set to true. 
     assert(found == true) 
    } 
    true 
    } 

는 기본적으로 validate 방법은 단지 MM1 가치의 확인을 모두 확인 MM2에 존재 (에 기반 "텍스트"키/속성), 다른 방법은 필요하지 않습니다. 그런 다음 mm1과 mm2의 각 요소의 속성 값이 동일한 지 확인합니다.

함수 프로그래밍 스타일에서 validate 메서드를 변환하려고합니다. 그러나 모든 mm1 항목을 검사하는 방법을 mm2 단위로 처리해야합니다. 내가 함께 노력 여기에서

에 대한-이해 :

def validate2(mm1: List[Map[String, Any]], mm2: List[M]): Boolean = {   
    for { 
     m1 <- mm1 
     a = m1("a") 
     m2 <- mm2 
    } { 
     if (a == m2.a) { 
     assert(m1("b") == m2.b) 
     } 
    } 
    true 
    } 

정말 좋은하지, 내가 이해를위한 내부 var found = false을 넣지 수 있기 때문이다. 그래서 mm1의 모든 항목이 mm2에 존재하는지 검사 할 수 없습니다.

누구나 도움이되거나 더 좋은 아이디어가있을 수 있습니다 (어쩌면 재귀를 사용하거나 var found을 사용하지 않고)?

답변

0

아마도, 이런 식으로 뭔가를 생각해

(컬렉션의 모든 요소를 ​​만족하는 경우 술어를 받아 true를 돌려)이 forall를 사용하여 (내 눈에) 꽤 명확하게 기록 할 수
val ms = mm2.map(m => m.a -> m.b).toMap 
mm1.foreach { m => 
    assert(m.get(a).flatMap(ms.get).exists(_ == m("b"))) 
} 

true 
+0

미안하지만, 네가 여기서 무엇을 목표로하고 있는지 정확히 모르겠다.하지만 그게 효과가 있다고 생각하지 않는다. 그리고 네가 말하는 것처럼 말하지 않고 일종의 센티널 가치로 사용한다. 하고있는 것은 나쁜 생각입니다. –

+0

좋은 지적. 감시 카메라를 제거했습니다 ... 왜 그것이 작동하지 않는다고 말하는가? 나는 그것이 정말로 확실하다. – Dima

+0

항상 사실을 반환 할 것입니다. –

2

및 (또한 조건이 필요하지만 하나 개의 일치 필요) exists : 내가 잘못에 대한 예외와 함께 실패 할 assert를 사용하지 않는

def validate(mm1: List[Map[String, Any]], mm2: List[M]) = mm1.forall { m1 => 
    mm2.exists { 
    case M(a, b) => a == m1("a") && b == m1("b") 
    } 
} 

참고 입력-이 본질적으로 작동하지 않습니다, 그리고 그것은 꼬마 도깨비를 나누기 메소드의 형식 시그니처의 불법적 인 계약 - 부울 값을 반환하는 validate(...) 메소드가 표시되면 인수가 유효한 경우 해당 값이 true이고 그렇지 않은 경우 false라고 가정합니다. 원래 버전과 동일한 동작을 구현하기 위해 예외 및 기능 결합 자의 하이브리드를 사용할 수 있지만 그렇게하지 않는 것이 좋습니다.

그래도 get 또는 getOrElse을 사용하고 명시 적으로 오류의 가능성을 처리하고, Map[String, Any]을 사용하지 않는지도에서 조회를 피하는 것이 좋습니다.

+0

O (n^2) not good : -/ – Dima

+2

OP의 코드는 동일합니다. 질문은 최적화가 아닌 기능 스타일로 다시 작성하는 것에 관한 것입니다. –

+1

또한 Op 코드는 항상 true를 반환합니다 ... 귀하는 그렇지 않습니다;) – Dima

관련 문제