2017-04-17 1 views
1

각 레코드의 두 번째 요소로 레코드 시퀀스를 정렬하려고합니다. 문제는 이것들이 값이 아니고 그저 하나의 타입이라는 것입니다. 내가 어떤 유형을 기반으로 값을 반환하는 함수가 있습니다.F # 값이 아직 시퀀스에서 유형에 할당되지 않은 레코드의 정렬 순서

type Suit = Spades | Clubs | Hearts | Diamonds 
type Rank = Ace | Two | Three | Four | Five | Six | Seven | Eight | Nine | Ten | Jack | Queen | King 
type Card = { suit: Suit; rank: Rank} 

type Hand = Card seq 

let cardValue(card:Card) = 
    if (card.rank = Ace) then 1 
    elif (card.rank = Two) then 2 
    elif (card.rank = Three) then 3 
    elif (card.rank = Four) then 4 
    elif (card.rank = Five) then 5 
    elif (card.rank = Six) then 6 
    elif (card.rank = Seven) then 7 
    elif (card.rank = Eight) then 8 
    elif (card.rank = Nine) then 9 
    elif (card.rank = Ten) then 10 
    elif (card.rank = Jack) then 10 
    elif (card.rank = Queen) then 10 
    elif (card.rank = King) then 10 
    else 0 

let sortHandByValue(hand:Hand) = 
......missing code here...... 

를하고 내가 뭘하려고 오전 값으로 순위를 기준으로 정렬 손입니다 :

이 내가 가진 것입니다.

예를 들면 손은 현재 {{Hearts; 세}; {스페이드 한 벌; 잭}; {다이아 패 한 벌; 2}}

결과가 다음과 같이 정렬됩니다. {{Diamonds; 두}; {하트; 세}; {스페이드 한 벌; Jack}}

Seq.sort |> Seq.groupBy id |> Seq.map snd하지만 값으로 정렬하고 알파벳순으로 만 정렬하지 않습니다.

유형을 변경할 수는 없지만 다른 모든 것은 변경할 수 있습니다. 감사합니다. 감사합니다.

+0

시퀀스는 튜플이 아니라 레코드입니다. – s952163

+1

'hand |> Seq.sortBy cardValue' ..? – ildjarn

+0

나는 또한'Rank * Suit'가 소화하기 더 쉽다고 생각한다. – s952163

답변

2

레코드를 표시 할 때 코드를 약간 정리해야합니다. 카드 유형을 튜플 및 일치 함수로 다시 작성했습니다. 그런 다음 당신이 필요로하는 모든이 (sortby 종류의 오름차순으로) Seq.sortBy 또는 Seq.sortByDescending에 파이프입니다 : 레코드

type Suit = Spades | Clubs | Hearts | Diamonds 
type Rank = Ace | Two | Three | Four | Five | Six | Seven | Eight | Nine | Ten | Jack | Queen | King 
type Card = Suit * Rank 

type Hand = Card seq 

let cardValue (card:Card) = 
    match card with 
    | _, Ace -> 1 
    | _, Two -> 2 
    | _, Three -> 3 
    | _, Four -> 4 
    | _, Five -> 5 
    | _, Six -> 6 
    | _, Seven -> 7 
    | _, Eight -> 8 
    | _, Nine -> 9 
    | _, Ten | _, Jack | _, Queen | _, King -> 10 


let hand = seq [(Hearts, Three); (Spades, Jack); (Diamonds, Two)] 

hand |> Seq.sortBy cardValue 
//val it : seq<Suit * Rank> = 
//seq [(Diamonds, Two); (Hearts, Three); (Spades, Jack)] 

버전 : 나는 원래 이렇게 가까이를 유지했다.

/// Version with Records 
type Suit = Spades | Clubs | Hearts | Diamonds 
type Rank = Ace | Two | Three | Four | Five | Six | Seven | Eight | Nine | Ten | Jack | Queen | King 
type Card = { suit: Suit; rank: Rank} 
type Hand = seq<Card> 

let cardValue(card:Card) = 
    if (card.rank = Ace) then 1 
    elif (card.rank = Two) then 2 
    elif (card.rank = Three) then 3 
    elif (card.rank = Four) then 4 
    elif (card.rank = Five) then 5 
    elif (card.rank = Six) then 6 
    elif (card.rank = Seven) then 7 
    elif (card.rank = Eight) then 8 
    elif (card.rank = Nine) then 9 
    elif (card.rank = Ten) then 10 
    elif (card.rank = Jack) then 10 
    elif (card.rank = Queen) then 10 
    elif (card.rank = King) then 10 
    else 0 

let hand = seq [{suit=Hearts; rank=Three}; {suit=Spades;rank=Jack}; {suit=Diamonds;rank= Two}] 

hand |> Seq.sortBy cardValue 

발 그것을 서열 = 서열 [{소송 = 다이아몬드; 순위 = 2;}; {소송 = 하트; 순위 = 3;}; {옷 = 스페이드; rank = Jack;}]

+1

나는 도움과 설명을 높이 평가했지만 불행히도 나는 타입 카드를 바꿀 수 없다. 그래서 카드를 값과 비교해 보았을 때, 'Card'타입이 아니라 "a * 'b'라고 불평하고 있습니다. – TJ8

+0

그건별로 문제가되지 않습니다. 마지막 줄 만 있으면됩니다 :-) 레코드 버전을 추가하겠습니다. 튜플 태그를 제거하고 약간의 문구를 다시 말해야합니다. – s952163

+0

혼란스러워서 죄송합니다. 나는 F #을 오랫동안하지 않았고 나의 용어는 최고의 하하가 아니다. – TJ8

관련 문제