### Author Topic: Sort into Buckets!  (Read 1526 times)

0 Members and 1 Guest are viewing this topic.

#### zoltan

• Guest
##### Sort into Buckets!
« on: December 30, 2008, 04:25:44 PM »
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.

Code: [Select]
`(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.