Request for deselect function

Started by TedWalther, November 19, 2009, 01:14:59 AM

Previous topic - Next topic

TedWalther

The select function lets me pick various values from a list to form a new list.



Could we have the corollary as a built in?  deselect would return the whole list but WITHOUT the listed items.



(setq a '(1 2 3 4 5))

(select a 1 2 3) => (2 3 4)
(deselect a 1 2 3) => (1 5)
Cavemen in bearskins invaded the ivory towers of Artificial Intelligence.  Nine months later, they left with a baby named newLISP.  The women of the ivory towers wept and wailed.  \"Abomination!\" they cried.

Lutz

#1
depending on the application you could use difference:


> (setq a '( 1 2 3 4 5))
(1 2 3 4 5)
> (difference a (select a 1 2 3))
(1 5)
>


it is not always the same as a deselect, but in this case it is. Nobody has ever asked for this before - what would you use it for?

TedWalther

#2
I'm trying to merge sublists of a list that share common elements.  Its a good little puzzle.  Because every time I merge two lists, now I have to go back and start at the beginning with the comparisons, because the left hand side is a new and different set of elements.



So, for instance, if I'm iterating over a list, and comparing every element with every other element, I'd do like this:



(dolist (x lst)
  (filter (fn (y) (= x y)) (deselect lst $idx)))


I do this sort of thing when generating all possible poker hands, and also I'm consolidating Strong's numbers  from some XML I have to reduce the 8000 numbers to 6000 numbers.



Ted
Cavemen in bearskins invaded the ivory towers of Artificial Intelligence.  Nine months later, they left with a baby named newLISP.  The women of the ivory towers wept and wailed.  \"Abomination!\" they cried.

Kazimir Majorinc

#3
If I understood you well, difference could be pushed one level inside something like](set 'a '(101 102 103 104 105))

(select a (difference (sequence 0 (length a)) '(0 1 3 5))) => (103 105)[/b]



I said something like, because select has bit strange behaviour which might be bug or not. Dependently on that, (sequence 0 (length a)) might be adjusted.



> (select '(100 101 102) '(1))

(101)

> (select '(100 101 102) '(2))

(102)

> (select '(100 101 102) '(3))

(102)

> (select '(100 101 102) '(4))

(102)

> (select '(100 101 102) '(7))

(102)


>



The way you use deselect, it looks to me like pop, with difference that pop is destructive, while select, filter, clean are not - but it could be combined with copy for your purpose. For very example you shown, i.e. removing duplicated from list, Newlisp has function unique, but for more general problems, I sometimes use dummy variables and make changes "in site", and consolidate the list later. Brute, but simple. Like making checks on grocery list.



(set 'L '(1 2 9 3 4 5 4 3 2 6 1 2 4))

(dolist(j L)
  (set 'jdx $idx)
  (dolist(i L)
    (when (and (> $idx jdx) (= i j))
          (setf (L $idx) 'for-deletition))))

(set 'L (clean (lambda(x)(= x 'for-deletition)) L))

(println L)
(exit)


But - all at all, your request for deselect has sense - I mean, if there is a pair (clean, filter) then why not (select, deselect)?[/color]
http://kazimirmajorinc.com/\">WWW site; http://kazimirmajorinc.blogspot.com\">blog.

TedWalther

#4
You are right Kazimir, deselect would be like pop+copy, but it would be a nice shorthand instead of having to do a sequence of pop+copy; sometimes the list to be deselected is the result of a series of calculations, and would allow me to avoid a let-block.  And you are also right, it seems to fit with the clean/filter paradigm.
Cavemen in bearskins invaded the ivory towers of Artificial Intelligence.  Nine months later, they left with a baby named newLISP.  The women of the ivory towers wept and wailed.  \"Abomination!\" they cried.