2013-03-03 2 views
1

예. 2 차원 배열이고 튜플에 일부 인덱스를 저장합니다.Scala에서 다차원 배열 uncurrying/tupling?

val testArray = Array.ofDim[Double](3, 4) 
val ixs = (1,2) 

이 튜플을 직접 사용하고 싶습니다. testArray(ixs). 그러나 Function.tupled(testedArray _)은 "_ 반드시 메서드를 따라야하며 Array [Array [Double]]을 따라갈 수 없습니다."를 반환합니다.

Array은 실제로 Function3의 하위 유형이 아니기 때문에입니까? 그렇다면이 제한 사항을 해결하는 방법은 무엇입니까? ArrayOps 또는 그와 비슷한 것을 내포해야합니까? 현재 해결 방법으로 데이터를 Map에 저장하고 있습니다.

답변

2

배열 배열에는 특별한 처리가 없습니다. 그들은 단지 (무언가)의 배열 일뿐입니다. 따라서 튜플을 통해 액세스하는 특별한 방법은 없습니다. 그러나 당신이 제안한 것처럼, 당신은 그런 방법을 만들 수 있습니다.

당신은

implicit class ArrayOps2D[@specialized T](xss: Array[Array[T]]) { 
    def apply(ij: (Int, Int)) = xss(ij._1)(ij._2) 
    def apply(i: Int, j: Int) = xss(i)(j) 
    def update(ij: (Int, Int), t: T) { xss(ij._1)(ij._2) = t } 
    def update(i: Int, j: Int, t: T) { xss(i)(j) = t } 
} 

당신은

implicit class ArrayOps2D[T](val xss: Array[Array[T]]) extends AnyVal { 
    def apply(ij: (Int, Int)) = xss(ij._1)(ij._2) 
    def apply(i: Int, j: Int) = xss(i)(j) 
    def update(ij: (Int, Int), t: T) { xss(ij._1)(ij._2) = t } 
    def update(i: Int, j: Int, t: T) { xss(i)(j) = t } 
} 

일을 생각 할 수 있지만, 이것은 내 의견으로는 잘 작동하지 않습니다. 구현 한계로 인해 AnyVal을 특수화 할 수 없습니다. 게다가 원시는 boxing을 피할 수 있기 때문에 프리미티브를 많이 사용하는 편이 낫습니다. (그리고 JVM은 객체 생성을 피할 수 있습니다.) 예를 들어 문자열) 당신은 (형식적으로) 객체를 생성하지 않기 때문에. 하지만 당신의 예제는 프리미티브를 사용합니다.

어떤 경우이든 튜플과 인수 쌍을 사용하여 두 개의 인덱스를 완벽하게 처리 할 수 ​​있습니다 (작성한 것처럼). 업데이트 방법을 완벽하게 사용할 수는 없습니다. 대부분 효과가 있지만 이 자동으로 숫자 유형을 홍보하지 않습니다. 따라서 double 값을 가지고 a(1,2) = 3이라고 쓰면 update(Int, Int, Int) 메서드를 찾지 못해서 실패하고 update(Int, Int, Double)을 사용하지 않을 것입니다. 그러나 전환 (또는이 경우에는 3d 작성)을 수행하여 직접 수정할 수 있습니다.

+0

두 접근법 간의 절충에 대한 포괄적 인 토론에 감사드립니다. –

+0

또한 구현 방식에 따라 (스칼라 2.10+) "값을 가지는 AnyVal"클래스를 사용하여 값 클래스를 사용할 수 있습니다. core/value-classes.html). –

+0

@ TheTerribleSwiftTomato - 무슨 뜻인지 잘 모르겠습니다. 2.10에서는'special' 키워드를 실제로 사용할 수 없으며 "unexpected-box-element"라는 일반 버전을 "당신이 생각하고 있을지도 모르는"버전으로 이미 커버했습니다. –