Visual LISP, AutoLISP and General Customization
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

sorting a list of lists

8 REPLIES 8
SOLVED
Reply
Message 1 of 9
mracad
2907 Views, 8 Replies

sorting a list of lists

I am trying to sort a list of lists by the size of units.

 

Here is the unsorted list -

(setq List_Blocks
  (list
    (list "10x10" "UNIT DOWN-CC" 56)
    (list "7.5x10" "UNIT DOWN-CC" 20)
    (list "5x5" "UNIT DOWN-CC" 34)
    (list "10x15" "UNIT EXTERIOR" 32)
    (list "5x10" "UNIT DOWN-CC" 31)
    (list "10x20" "UNIT EXTERIOR" 24)
    (list "10x30" "UNIT EXTERIOR" 13)
    (list "10x25" "UNIT EXTERIOR" 2)
  )
)

 

I would like the list sorted by the first number before the "X" and then by the second number after the "X".

 

Example of sorted list -

    (list "5x5" "UNIT DOWN-CC" 34)

    (list "5x10" "UNIT DOWN-CC" 31)

    (list "7.5x10" "UNIT DOWN-CC" 20)

    (list "10x10" "UNIT DOWN-CC" 56)
    (list "10x15" "UNIT EXTERIOR" 32)
    (list "10x20" "UNIT EXTERIOR" 24)
    (list "10x25" "UNIT EXTERIOR" 2)

    (list "10x30" "UNIT EXTERIOR" 13)

 

Thanks in advance!!!

Tags (3)
8 REPLIES 8
Message 2 of 9
alanjt_
in reply to: mracad

This should do it... (defun _sort (lst) (vl-sort lst (function (lambda (a b) (< (car a) (car b))))))

Message 3 of 9
alanjt_
in reply to: alanjt_

Oops. Disregard my first post. I wasn't thinking about the items being strings. Try this, converts string to real for proper sorting.

 

(defun _sort (lst) (vl-sort lst (function (lambda (a b) (< (atof (car a)) (atof (car b)))))))

 

Message 4 of 9
Kent1Cooper
in reply to: alanjt_


@alanjt_ wrote:

This should do it... (defun _sort (lst) (vl-sort lst (function (lambda (a b) (< (car a) (car b))))))


That puts all the 10's first, followed by the 5's, and the 7.5 last, because it orders by the first character, not the numerical value represented prior to the x.  I had tried this:

 

(vl-sort lst '(lambda (x y) (< (atof (car x)) (atof (car y)))))

 

which reads only the characters prior to the x, and at least gets all the 5's first followed by the 7.5 and then the 10's, but it also needs further elaboration.  It puts all those with the same starting numerical characters together, and with the groupings in ascending order of the starting numbers, but within each grouping, they're just in the order in which they occur in the original list [in the OP's, 10x25 comes last, rather than before 10x30].

 

I think I recall something not too different from this coming up before.  A Search may find it, but I haven't tried searching.

Kent Cooper, AIA
Message 5 of 9
alanjt_
in reply to: Kent1Cooper

@Kent: see my 2nd post. I realized the problem after my first post.

Message 6 of 9
Kent1Cooper
in reply to: alanjt_


@alanjt_ wrote:

@KenT: see my 2nd post. I realized the problem after my first post.


Yes, we crossed in the mail.  But as with my similar version, that still leaves them not in the right order within those that start with the same numbers [unless those occur in the right order within the starting list].  However, this seems to do that, in very limited testing:

 

(vl-load-com); [if needed]

(defun testsort (lst / afterx)
  (defun afterx (str)
    (atof (substr str (+ 2 (vl-string-search "x" str))))
  ); defun -- afterx
  (vl-sort ; by starting numbers on the list pre-sorted:
    (vl-sort ; by end numbers first
      lst
      '(lambda (a b) (< (afterx (car a)) (afterx (car b))))
    ); vl-sort [inner]
    '(lambda (x y) (< (atof (car x)) (atof (car y))))
  ); vl-sort [outer]
); defun -- testsort

 

I wouldn't be surprised if there's a more efficient way to do it.

Kent Cooper, AIA
Message 7 of 9
mracad
in reply to: Kent1Cooper

Kent,

thanks...that was perfect!

Message 8 of 9
alanjt_
in reply to: Kent1Cooper

Ahh, I completely overlooked consideration of the 2nd number.

Message 9 of 9
pbejse
in reply to: mracad

Another variation

 

(defun testsort2 (lst / _numit)
  (defun _numit (s)
    (read (strcat "(" (vl-string-subst " " "x" s) ")")
    ) ;_ read
  ) ;_ defun
  (vl-sort lst
           '(lambda (l m)
              (setq l (_numit (car l))
                    m (_numit (car m))
              ) ;_ setq
              (cond
                ((< (car l) (car m)) T)
                ((= (car l) (car m)) (< (cadr l) (cadr m)))
              ) ;_ cond
            ) ;_ lambda
  ) ;_ vl-sort
) ;_ defun

 

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

”Boost