LISP 按 2 个参数对列表列表进行排序

LISP sort list of lists by 2 arguments

我有一个列表(preorder-mst),如下所示:

((arc graph-id vertex-a vertex-b weight) (arc graph-id vertex-a vertex-b weight) ...)

我想做的是按权重对子列表进行排序,如果 2 个权重相等,则按顶点 b。

我尝试调用函数对元素进行排序

(sort preorder-mst 'compare-string-number)

(defun compare-string-number (firstLIST secondLIST)
    (if (eql (fifth firstLIST) (fifth secondLIST))
        (if (string-lessp (fourth firstLIST) (fourth secondLIST))
            (fourth firstLIST)
            (fourth secondLIST))
        (when T
            (if (< (fifth firstLIST) (fifth secondLIST))
                (fifth firstLIST)
                (fifth secondLIST)))))

它 returns 是正确的值,但没有正确排序。知道它有什么问题吗?

我的(不需要的)输出:

((ARC GRAFO_TEST_1 C I 2) (ARC GRAFO_TEST_1 G H 1) (ARC GRAFO_TEST_1 NIL A 0) (ARC GRAFO_TEST_1 B C 8) (ARC GRAFO_TEST_1 A B 4))

排序中使用的谓词是这样工作的:它们有两个参数和 return true 或 false。如果 predicate returns true 那么排序时优先考虑第一个参数,否则 第二。要了解有关排序如何工作及其所需谓词的更多信息,请参阅 here

请记住,几乎所有值在 lisp 中都是“真实的”,而空列表或 nil 是假的。见于 hyperspec 术语 generalized boolean.

您的函数几乎总是 return 为真,因为它 return 是您要比较的元素,并且它们 有真实的价值观。要解决这个问题,您必须 return 比较本身:

(defun graph-sort-p (firstLIST secondLIST)
  (if (= (fifth firstLIST) (fifth secondLIST))
      (string-lessp (fourth firstLIST) (fourth secondLIST))
      (< (fifth firstLIST) (fifth secondLIST))))

(sort my-list  #'graph-sort-p)