问题
I am trying to sort a Sequence of records by the second element in each record. The problem is that these are not a value and instead are just a Type. I have a function where it returns the value based on which Type it is.
This is what I have:
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......
and what I am trying to do is sort Hand by the Rank as a value.
So for example Hand is currently : {{Hearts; Three}; {Spades; Jack}; {Diamonds; Two}}
It will sort Hand so the result is : {{Diamonds; Two}; {Hearts; Three}; {Spades; Jack}}
I tried doing hand |> Seq.sort |>Seq.groupBy id |> Seq.map snd but that doesn't sort it by value and only by alphabetical.
I cannot change any of the types, but I can change everything else. Any ideas would be appreciated, thanks!
回答1:
You need to clean up the code a bit as it shows records, I rewrote the Card type to be a tuple and the match function as well. Then all you needs is to pipe into Seq.sortBy
or Seq.sortByDescending
(as sortby sorts ascending):
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: I kept this close to your original.
/// 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
val it : seq = seq [{suit = Diamonds; rank = Two;}; {suit = Hearts; rank = Three;}; {suit = Spades; rank = Jack;}]
来源:https://stackoverflow.com/questions/43448162/f-sorting-sequence-of-records-where-value-isnt-yet-assigned-to-type-in-sequenc