如何在 Racket 中重新排列成对列表(包含字符或数字)的顺序?

How can I rearrange the order of a list of pairs (that have chars or numbers) in Racket?

如何在 Racket 中将所有带有字符 'A'K'Q'J 的牌移到手牌的前面,并将所有数字 1-10 移到手牌的末尾?

例如:((4 . ♠) (9 . ♣) (10 . ♠) (Q . ♦) (A . ♠))

变成

((A . ♠) (Q . ♦) (10 . ♠) (9 . ♣) (4 . ♠))

我在这里遇到的困难是处理数字和字符的混合。我可以使用 sort 函数对数字进行排序,但一旦出现字符,我就会出错。

基本上 sort 有一个可选的 less-than? 函数,您可以在其中检查第一个参数是否小于第二个参数。例如。想象一下,我想按卡片的价值 1-10 对卡片进行排序,而 J、Q、K、A 是 11-14:

;; produce a numeric value for all cards
(define (card->value c)
  (let ((v (car c)))
    (case v
      ((J) 11)
      ((Q) 12)
      ((K) 13)
      ((A) 14)
      (else v))))

(define cards '((4 . ♠) (9 . ♣) (10 . ♠) (Q . ♦) (A . ♠)))
(map card->value cards) ; ==>  (4 9 10 12 14)

(define (card-less? c1 c2)
   (< (card->value c1) (card->value c2)))

(sort '((4 . ♠) (9 . ♣) (10 . ♠) (Q . ♦) (A . ♠)) card-less?)
; ==> ((4 . ♠) (9 . ♣) (10 . ♠) (Q . ♦) (A . ♠))

由于您的顺序相反,因此您应该传递一个 card-greater? 而不是 card-less? 相反的 sort 将颠倒顺序。

如果您正在使用 #lang racket,您可以使用两个额外的可选值并在没有 card-less? 的情况下使用它:

(sort cards < #:key card->value     #:cache-keys? #t)
; ==> ((4 . ♠) (9 . ♣) (10 . ♠) (Q . ♦) (A . ♠))

您可以这样使用 sort function(sort sequence procedure)过程 可能如下所示:

(define sort/cards
  (lambda(a b)
    (if (check: a is member of the list '(A K Q J))
       true
       false)))

您可以开发 (check ...) 函数并删除 (if ...),因为检查将 return 适合排序的值。

如果要对字母进行进一步排序,需要在中比较abcheck.