2011-04-12 10 views
0

다음 스 니펫에서 dict 키를 형성하는 중첩 된 튜플에 포함 된 recid를 추출하려고합니다. 중첩 된 튜플 형식은 (Int32, (부울 값, 부울 값)) -변환/변환 문제

Int32 항목의 값 (실제로는 db 레코드의 행 ID )을 찾고 있습니다.

아래의 일치 코드에서 목록에 recid를 추가하려고하지만 먼저 정수로 개체를 캐스팅하려고합니다.
하지만 다음과 같은 오류가 발생합니다. 그 이유는 확실하지 않습니다.

오류 : 유형에서이 런타임 강제 또는 형식 시험 '는
이 프로그램 지점 이전 정보를 기반으로 불확실한 유형을 포함이 int32합니다. 일부 유형에서는 런타임 유형 테스트가 허용되지 않습니다. 추가 유형 주석이 필요합니다. 여기에 참조되는 사전은 다음과 같이 정의된다 rdict 가정

// Create Dict 
let rdict = new Dictionary<_,_>() 
// Add elements 
rdict.Add((x.["PatientID"],(true,true)),ldiff) 

// Extract Dict items 
let reclist = new ResizeArray<int32>() 
for KeyValue(k,v) in rdict do 
match k with 
    | ((recid,(true,true)) -> 
    printfn "Found a matching Record: %A " recid; // <- prints correct result 
    let n = (recid:?> int32)       // <- coercion error 
     reclist.Add(n) 
+0

라인'rdict.Add ((X. "PatientID"], (참, TRUE))'개폐 괄호의 일치 수를 갖는다. Dictionary'은'의 키 값은 무엇 'int * (bool * bool)'은 키 타입 일 뿐이고'int'는 키 타입이고'bool * bool'은 값 타입입니까? 또한'x의 실제 타입은 무엇입니까? "int"또는'int' (즉,'int'로 형 변환 될 수있는'obj')를 반환합니까? – ildjarn

+0

oops - rdict.add 행을 ​​게시 할 때 제가 놀았습니다. - 이제 수정되었습니다. (사실 저는/dict 값으로 행/열 쌍의 목록을 작성 해요. dict 키는 실제로 복합 (제거, (부울, 부울)) 값입니다. (boolean은 rec가 쌍으로 존재하는지 여부를 정의합니다. 테이블) x. [ "PatientID"]는 db 테이블에서 검색 한 (unboxed) int 값입니다. – BrendanC

+0

실제로 1 m ore 질문 - 동봉 된'bool' 쌍이'true, true'이고 다른 조합이 아닌 경우에만'rdict'에서'reclist'로 id를 복사하는 것이 당신의 의도입니까? – ildjarn

답변

1

다음 ResizeArray<int> 내가 제안 생산하는 Dictionary<int*(bool*bool), _>입니다 :

let reclist = 
    (ResizeArray<_>(), rdict.Keys) 
    ||> Seq.fold(fun list (id,_) -> list.Add id; list) 

또한, Dictionary<int*(bool*bool), _>는 이상한 저를 친다. 왜 Dictionary<int*bool*bool, _>? 즉, bool 쌍을 두 번째 튜플로 중첩하는 이유는 무엇입니까? 이 변경 한 경우, 하나는 너무 rdict.Add를 부를 것이다 :

rdict.Add ((x.["PatientID"], true, true), ldiff) 

그리고 reclist을 대신 할 것입니다 :

let reclist = 
    (ResizeArray<_>(), rdict.Keys) 
    ||> Seq.fold(fun list (id,_,_) -> list.Add id; list) 

편집 : 귀하의 코멘트에 당신은 구축 할 수있는 욕망을 언급 두 개의 서로 다른 조합에 따라 키에 ResizeArray을 분리하십시오. 여기에 대한 한 가지 생각이 있습니다.

+0

dict 키는 값으로 recid 만있는 초기 버전에서 발전했습니다. 논리적으로 나는 부울 값을 recid와 다소 다르게 보았 기 때문에, 그것들을 분리 된, 중첩 된 튜플에 넣었다고 생각한다. 당신의 접근 방식에 몇 가지 장점이 있습니다 - 여기서 당신의 도움을 구하십시오. – BrendanC

+0

@BrendanC :'int * (bool * bool)'에 비해'int * bool * bool'의 효율성은 (할당 횟수를 줄이는) 효율성이 유일합니다. 스타일리시하게도 당신이 가지고있는 것이 이상하게 느껴지 긴하지만, 그것이 당신에게 의미가있는 것이라면 나는 그것에 큰 해를 끼치 지 않습니다. : -] – ildjarn

0

완성도 및 향후 참조를 위해 추가 테스트를 기반으로 결과를 게시하고 싶습니다. 권투/언 박싱으로 이전에 게시 한 코드를 성공적으로 수정할 수있었습니다.

향후 다른 사람에게 유용하게 사용되기를 바랍니다.

// Add initial value note the box call here 
diff_dict.Add((box x.["PatientID"],(true,true)),ldiff) 


let reclist = new ResizeArray<int32>() 
for KeyValue(k,v) in rdict do 
    //printfn "Difference Dictionary - Key: %A; Value: %A; " k v 
    match k with 
     // extract the result - note the 'unbox' call 
     | (recid,(true,false)) -> let n:int32 = unbox recid 
            reclist.Add(n)