wharan 发表于 2023-7-5 12:08:14

求一个按长度拆分表成子表的函数

本帖最后由 wharan 于 2023-7-5 23:56 编辑

有一个表,表中有若干元素,要求把该表按长度拆分成子表。长度不足时用空格补足。

如:把表(1 2 3 4 5 6 7 8 9 10 11)按长度3拆分成((1 2 3) (4 5 6) (7 8 9) (10 11 ""))
      表(1 2 3) 按长度5拆分成(1 2 3 "" "")


yoyoho大侠的函数完美解决问题,在这里共享。
对所有热心的朋友表示感谢。

(defun list:split (lst x / lst2)
(setq lst3 lst)
(repeat (- x (rem (length lst) x))
      (setq lst3 (append lst3 (list "")))
)
(setq lst lst3)
(foreach n lst
    (if      (and lst2 (/= x (length (car lst2))))
      (setq lst2 (cons (append (car lst2)
                               (list n)
                     )
                     (cdr lst2)
               )
      )
      (setq lst2 (cons (list n) lst2))
    )
)
(reverse lst2)
)

yoyoho 发表于 2023-7-5 21:13:29

指令: (setq lst '(1 2 3 4 5 6 7 8 9 10 11))
(1 2 3 4 5 6 7 8 9 10 11)

指令: (list:split lst 15)
((1 2 3 4 5 6 7 8 9 10 11 "" "" "" ""))

指令: (list:split lst 3)
((1 2 3) (4 5 6) (7 8 9) (10 11 ""))

指令: (list:split lst 5)
((1 2 3 4 5) (6 7 8 9 10) (11 "" "" "" ""))

指令: (list:split lst 8)
((1 2 3 4 5 6 7 8) (9 10 11 "" "" "" "" ""))

yoyoho 发表于 2023-7-5 21:12:00

(defun list:split (lst x / lst2)
(setq lst3 lst)
(repeat (- x (rem (length lst) x))
      (setq lst3 (append lst3 (list "")))
)
(setq lst lst3)
(foreach n lst
    (if      (and lst2 (/= x (length (car lst2))))
      (setq lst2 (cons (append (car lst2)
                               (list n)
                     )
                     (cdr lst2)
               )
      )
      (setq lst2 (cons (list n) lst2))
    )
)
(reverse lst2)
)

ztj988 发表于 2023-7-5 13:38:15

(defun list-split (k lst / a bb-list-part i lst1 n)
        (defun bb-list-part
        (lst from to / l x)
        (repeat from (setq lst (cdr lst)))
        (repeat (1+ (- to from)) (setq l (cons (car lst) l)) (setq lst (cdr lst)))
        (REVERSE l)
)
        (setq n 0)
        (repeat (fix (/ (length lst ) k))
               
                (setq lst1 (append lst1 (list (bb-list-part lst n (+ n (1- k))))))
                (setq n (+ n k))
        )
        (if (/= (rem (length lst ) k) 0)
                (progn
                        (repeat (- k (rem (length lst ) k))
                        (setq a (cons "" a))       
                        )
                        (setq lst1 (append lst1 (list (append (bb-list-part lst n (1- (length lst )))a)) ))
                       
                       
                )
        )
        lst1
        )

vitalgg 发表于 2023-7-5 13:14:00

本帖最后由 vitalgg 于 2023-7-5 13:16 编辑




用 nil 补足不行吗?


命令:
命令: (list:split-3d '(1 2 3 4))
((1 2 3) (4 nil nil))

liuhe 发表于 2023-7-5 13:49:23

本帖最后由 liuhe 于 2023-7-6 14:18 编辑

(DEFUN LH:LSTTOLST (LST1 N / LHLSTADD LST2 TEMLST)
(defun LHLSTADD (LST1 N)
    (SETQ LST1 (REVERSE LST1))
    (REPEAT (- N (LENGTH LST1))
      (SETQ LST1 (CONS "" LST1))
    )
    (REVERSE LST1)
)
(REPEAT (FIX (/ (LENGTH LST1) N))
    (REPEAT N
      (SETQ TEMLST (CONS (CAR LST1) TEMLST)
      LST1   (CDR LST1)
      )
    )
    (SETQ LST2 (CONS (REVERSE TEMLST) LST2)
    TEMLST NIL)
)
(IF (> (REM (LENGTH LST1) N) 0)
    (REVERSE (CONS (LHLSTADD LST1 N) LST2))
    (REVERSE LST2)
)
)

这个简洁了

wharan 发表于 2023-7-5 15:27:41

liuhe 发表于 2023-7-5 13:49
看着都差不多

这个程序,结果返回有点问题。
(LH:LSTTOLST '(1 2 3 4 5 6 7 8 9 10 11) 5)返回((1 2 3 4 5) (6 7 8 9 10) ("" "" 11 "" ""))
希望返回:((1 2 3 4 5) (6 7 8 9 10) (11 "" "" "" ""))
(LH:LSTTOLST '(1 2 3 4 5 6 7 8 9 10 11) 15) 返回((1 2 3) (4 5 6) (7 8 9) (10 11 ""))
希望返回:(1 2 3 4 5 6 7 8 9 10 11 "" “” “” “”)

wharan 发表于 2023-7-5 15:49:52

ztj988 发表于 2023-7-5 13:38
(defun list-split (k lst / a bb-list-part i lst1 n)
        (defun bb-list-part
        (lst from to / l x)


这个函数,对于简单的表,没有问题。但对于复杂的表,可能不具有通用性。
比如:(list-split 3 '((1) (2) (3) (4) (5) (6) (7) (8) (9) (10) (11))).
作为函数,应该对变量表具有通用性

树櫴希德 发表于 2023-7-5 16:05:36

本帖最后由 树櫴希德 于 2023-7-6 14:42 编辑

(setq l0 '(1 2 3 4 5 6 7 8 9 10 11))
(setq l01 nil) (setq n 3)
(repeat (- n(rem(length l0)n))(setq l01 (append l0 (list ""))))
(setq ptlst1 nil)
(whilel01
   (setq ptlst nil)(repeat nn (setq ptlst (append ptlst (list(car l01) ))) (setq l01(vl-remove (car l01) l01) ))
       (setq ptlst1 (append ptlst1 (list ptlst) ))      

);;;;;;;

(setq l0 '(1 2 3 4 5 6 7 8 9 10 11))
;(setq l01 nil)
(setq nn 3)
;(repeat (- n(rem(length l0)n))(setq l01 (append l0 (list ""))))
(setq ptlst1 nil)
(whilel0
   (setq ptlst nil)(repeat nn (setq ptlst (append ptlst (list(car l0) ))) (setq l0(vl-remove (car l0) l0) ))
       (setq ptlst1 (append ptlst1 (list ptlst) ))      

)
(setq ptlst1 (mapcar '(LAMBDA (y)(vl-remove-if-not '(LAMBDA (x) (/= x nil) ) y)    )   ptlst1))
;命令: !ptlst1
;((1 2 3) (4 5 6) (7 8 9) (10 11))

wharan 发表于 2023-7-5 16:11:14

vitalgg 发表于 2023-7-5 13:14
用 nil 补足不行吗?
这个函数比较简洁,具有通用性。但没有补位。

(defun list:split (lst x / lst2)
(foreach n lst
    (if        (and lst2 (/= x (length (car lst2))))
      (setq lst2 (cons (append (car lst2)
                             (list n)
                     )
                     (cdr lst2)
               )
      )
      (setq lst2 (cons (list n) lst2))
    )
)
(reverse lst2)
)

页: [1] 2
查看完整版本: 求一个按长度拆分表成子表的函数