Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
4.5k views
in Technique[技术] by (71.8m points)

sorting - LISP sort list of lists by 2 arguments

I have a list made out of lists (preorder-mst) like this:

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

What I wanted to do was to sort the sublists by weight and, if 2 weights were equal, by vertex-b.

I tried to call a function to sort the elements

(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)))))

It returns the correct value but doesn't sort them correctly. Any idea what is wrong with it?

My (undesired) output:

((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))


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Predicates used in sort work like this: they take two arguments and return true or false. If the predicate returns true then the first argument is considered in priority while sorting, else the second. To learn more about how sort works and the predicate it requires see here.

Remember that almost all values are "truthy" in lisp, while the empty list or nil are false. See in the hyperspec the term generalized boolean.

Your function almost always returns true, since it returns the elements you want to compare and they have truthy values. To fix that you have to return the comparisons themselves:

(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)

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...