Group List by Number

The following functions will group items in a supplied list into sublists of a given length (or less than the given length if the number of items in the original list is not evenly divisible by the group size).

Both functions will return a list of lists, in which the number of items within each sublist is at most the length specified by the second function argument.

Such functions are particularly useful when converting the 1-dimensional continuous list of x, y, & z coordinate values as returned by the ActiveX Coordinates property for a 2D or 3D polyline into a list of 2D or 3D points.

Groups of Maximum Length

Function Syntax (LM:group<n <l> <n>)
Current Version 1.0
Donate
Arguments
Symbol Type Description
l List List to process
n Integer Maximum number of items in each sublist (n > 0)
Returns
Type Description
List A list of lists, each of maximum length 'n', grouping elements of the original list

Function Description

This function will group items of a supplied list into lists of a maximum given length, that is, if the supplied list contains a number of items which is not evenly divisible by the group size, the last sublist in the list returned by the function will contain fewer items.

Recursive Version

Select all
;; Group by Number  -  Lee Mac
;; Groups a list 'l' into a list of lists, each of max length 'n'

(defun LM:group<n ( l n )
    (if l (LM:group<n-sub (cons nil l) n n))
)
(defun LM:group<n-sub ( l m n )
    (if (and (cdr l) (< 0 n))
        (LM:group<n-sub (cons (cons (cadr l) (car l)) (cddr l)) m (1- n))
        (cons (reverse (car l)) (LM:group<n (cdr l) m))
    )
)

Iterative Version

Select all
;; Group by Number  -  Lee Mac
;; Groups a list 'l' into a list of lists, each of max length 'n'

(defun LM:group<n ( l n / a b m )
    (while l
        (setq m n)
        (while (and l (< 0 m))
            (setq a (cons (car l) a)
                  l (cdr l)
                  m (1- m)
            )
        )
        (setq b (cons (reverse a) b)
              a nil
        )
    )
    (reverse b)
)

Example Function Calls

As shown by the last example, if the supplied list does not divide evenly into lists of the specified length, the last sublist will contain fewer items.

_$ (LM:group<n '("A" "B" "C" "D" "E" "F") 2)
(("A" "B") ("C" "D") ("E" "F"))
_$ (LM:group<n '(0 1 2 3 4 5) 3)
((0 1 2) (3 4 5))
_$ (LM:group<n '(0 1 2 3 4 5) 4)
((0 1 2 3) (4 5))

Groups of Fixed Length

Function Syntax (LM:group-n <l> <n>)
Current Version 1.0
Donate
Arguments
Symbol Type Description
l List List to process
n Integer Number of elements by which to group the list (n > 0)
Returns
Type Description
List A list of lists, each of length 'n', grouping elements of the original list

Function Description

This function will group elements of a supplied list into lists of a fixed length, that is, if the supplied list contains a number of items which is not evenly divisible by the group size, the last sublist in the list returned by the function will contain nil values to ensure all sublists are of the same fixed length/size.

Recursive Version

Select all
;; Group by Number  -  Lee Mac
;; Groups a list 'l' into a list of lists, each of length 'n'

(defun LM:group-n ( l n / r )
    (if l
        (cons
            (reverse (repeat n (setq r (cons (car l) r) l (cdr l)) r))
            (LM:group-n l n)
        )
    )
)

Iterative Version

Select all
;; Group by Number  -  Lee Mac
;; Groups a list 'l' into a list of lists, each of length 'n'

(defun LM:group-n ( l n / a b )
    (while l
        (repeat n
            (setq a (cons (car l) a)
                  l (cdr l)
            )
        )
        (setq b (cons (reverse a) b)
              a nil
        )
    )
    (reverse b)
)

Example Function Calls

As shown by the last example, if the supplied list does not divide evenly into lists of the specified length, nil values will occupy the remainder list elements.

_$ (LM:group-n '("A" "B" "C" "D" "E" "F") 2)
(("A" "B") ("C" "D") ("E" "F"))
_$ (LM:group-n '(0 1 2 3 4 5) 3)
((0 1 2) (3 4 5))
_$ (LM:group-n '(0 1 2 3 4 5) 4)
((0 1 2 3) (4 5 nil nil))

Example Program

The following example program demonstrates how this function may be used to group the 1-dimensional list of coordinate values returned by the ActiveX Coordinates property into a list of 2D or 3D points representing the vertices of a selected 2D or 3D polyline:

Select all
(defun c:getvertices ( / obj sel )
    (if (setq sel (ssget "_+.:E:S" '((0 . "*POLYLINE"))))
        (mapcar 'print
            (LM:group-n
                (vlax-get (setq obj (vlax-ename->vla-object (ssname sel 0))) 'coordinates)
                (if (= "AcDbPolyline" (vla-get-objectname obj)) 2 3)
            )
        )
    )
    (princ)
)
(vl-load-com) (princ)

textsize

increase · reset · decrease

Designed & Created by Lee Mac © 2010