Here is a function I came up with after realizing that this is something I routinely have to do in code with many different conditions.
It takes a list of elements and categorizes them into list of elements that have the have result of a test function. The syntax is the same as the VL-Sort function.
(Defun Categorize ( LST FUNK / lstSubList lstReturn)
(ForEach atm LST
(If (SetQ lstSubList (Car (VL-Member-If (Function (Lambda (l) (Eq (Apply FUNK (List atm)) (Apply FUNK (List (Car l)))))) lstReturn)))
(SetQ lstReturn (Subst (Reverse (Cons atm (Reverse lstSublist))) lstSubList lstReturn) )
(SetQ lstReturn (Reverse (Cons (List atm) (Reverse lstReturn))) )
)
)
lstReturn
)
For example, you could sort a list of number based on how they are divisible by a number:
_$ (Categorize (List 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15) (Function (Lambda (l) (Fix (/ l 5.0)))) )
((1 2 3 4) (5 6 7 8 9) (10 11 12 13 14) (15))
_$
You could sort a list of entities by their layer or other property:
(Categorize lstEnts (Function (Lambda (l) (Cdr (Assoc 8 (EntGet l))))) )
It's not very efficient since it runs the test function a lot and also suffers from the double reverse that is required to get the output lists in somewhat the same order as the input list. I guess if you were not concerned with the order of the output, you could lose the Reverse calls. To speed things up, I was thinking about having it cache a list of results that it could test each element against instead of running the test function through the return list every time. Also, some lisp purist could come up with a way to do it in classic lisp without the use of the VL-Member-If.
See what you think.