Uh...right. Of course. Obvious.
Ok..let's see if I can follow what you're doing. First, you're parsing the list of indices - instead of the list of source items. Which means...probably much faster operation as the selected indices are going to be less that the source list. Make sense.
Now you're...selecting an item from the list and if it's non-nil continue. Then you add to the include list. And at the same time delete from the source list...yielding the not-included list on finish. Simple.
Couple questions come up:
1. What is the purpose of the initial (reverse)? Because these lists (at least one of them) themselves get added to other lists later the order is irrelevant - I'll need to run a sort afterwards regardless.
2. The apparently redundant (setq a (nth i thelist)) in the (cons - was that a simple oversight in a quick post or were you waiting to see if I caught it? Or is there a purpose I'm not seeing?
3. My initial setup has "indices" as strings - so I needed to adjust (nth i thelist) into (nth (atoi i) thelist). However - that had a side effect that if the "indices" list is empty - the function will always select the first item. I started with these lines in the calling function:Code - Auto/Visual Lisp: [Select]
and changed to:Code - Auto/Visual Lisp: [Select]
Now I no longer need the (atoi) in the split function and all is well.
4. In terms of "expense" - how much overhead does "vl-remove" add to the processing? I'm assuming since you recommended it it's a good choice - for some reason I got it stuck in my head that the "vl-" functions in general are "bad" and additionally I somehow thought direct list manipulation would be expensive as well. I'm probably wrong thinking all around - I'd appreciate a cognitive recalibration here.
1. The reverse was there so CONS would place the indexed items in the same order. This could be achieved with a reverse at the end too though.
Good point .. maybe a (vl-sort indices '>) :)
1. The reverse was there so CONS would place the indexed items in the same order. This could be achieved with a reverse at the end too though.
I think in this case the reverse needs to be where it is so the indices list gets processed big to small. Otherwise the nth's get messed up as you start taking items off the front of the list. Unless we can guarantee that the indices list will always be chronologically sorted small to large from the start, you may want to sort it first (big to small) instead of reversing.
(defun foo (x i l / res)
(cond ((null i) (list nil l))
((= x (car i))
(setq res (foo (1+ x) (cdr i) (cdr l)))
(cons (cons (car l) (car res)) (cdr res))
)
(T
(setq res (foo (1+ x) i (cdr l)))
(list (car res) (cons (car l) (cadr res)))
)
)
)
_$ (foo 0 '(1 3) '("alpha" "bravo" "charlie" "delta" "echo"))
(("bravo" "delta") ("alpha" "charlie" "echo"))
ROY_SPLIT_VIA_INDICES
LEE_FOO2
RJP_FOO
(1 3) Benchmarking ...................Elapsed milliseconds / relative speed for 65536 iteration(s):
(RJP_FOO L I)...................1125 / 2.76 <fastest>
(ROY_SPLIT_VIA_INDICES L I).....1235 / 2.52
(LEE_FOO2 L I)..................3110 / 1.00 <slowest>
; 6 forms loaded from #<editor "<Untitled-0> loading...">
_$
(split-from-list '(1 3) '("alpha" "bravo" "charlie" "delta" "echo"))
Command: (split-from-list '(1 3) '("alpha" "bravo" "charlie" "delta" "echo"))
(("bravo" "delta") ("alpha" "charlie" "echo"))
Elapsed milliseconds / relative speed for 32768 iteration(s):
(_FOO THELIST INDICIES)..................1172 / 2.60 <fastest>
(FOO 0 INDICIES THELIS)..................1172 / 2.60
(SPLIT-FROM-LIST INDICIES THELIST).......1266 / 2.41
(SPLIT_VIA_INDICES THELIST INDICIES).....1312 / 2.32
(FOO2 INDICIES THELIST)..................3047 / 1.00 <slowest>
---- Benchmark utility: In memory of Michael Puckett ----
---- Benchmark utility: In memory of Michael Puckett ----
Quote---- Benchmark utility: In memory of Michael Puckett ----
I like that :-)