emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Contribution remove-from-list


From: Vincent Belaïche
Subject: Contribution remove-from-list
Date: Fri, 09 May 2008 12:56:14 +0200
User-agent: Thunderbird 2.0.0.14 (Windows/20080421)

Hello,

I have written the following remove-from-list function. I am not sure, maybe this already exists, but I could not find any such thing.

I find remove-from-list more convenient to tailor some lists in a more futureproof way than overwritting the full list. Maybe this can be useful to somebody-else. Please feel free to reuse/modify/etc... the following code:

;--------------------- contribution start ------------------------------------------------------------
(defun remove-from-list (lst-var predicate &optional remove-count from-end)
 "remove-from-list does the reverse operation of add-to-list.
Remove elements from list LST-VAR on which matching PREDICATE

PREDICATE may have two forms:

In the 1st form PREDICATE is a quote function is that case
matching predicate means that calling predicate with list element
in argument returns non nil,
for instance evaluation of
 \(defvar toto '\(1 2 3\)\)
 \(remove-from-list 'toto \(lambda \(x\) \(= x 2\)\)\)
will set toto to \(1 3\)

In the 2nd form PREDICATE is not a function, then the behaviour
is the same as if \(lambda \(x\) \(equal x PREDICATE\)\) was used
instead using the 1st form
so that evalution of \(defvar toto
'\(1 2 3\)\) \(remove-from-list 'toto 2\) will also set toto to
\(1 3\)

Note that if you want to remove an element that is a function, then only the
1st form can be used.

REMOVE-COUNT is the maximum number of removals when it is a positive number
non nil means infinite (remove all occurences)
else remove only the 1st occurrence

In case of limited removal count list is processed from start by default
and from end if FROM-END is non nil

so evalution of
 \(defvar toto '\(1 2 2 3 2\)\)
 \(remove-from-list 'toto 2\)
\(remove-from-list '\(1 2 2 3 2\) 2\)
will set toto to \(1 3 2\)

and evalution of
 \(defvar toto '\(1 2 2 3 2\)\)
 \(remove-from-list 'toto 2 t\)
will set toto to \(1 2 2 3\).
"
 (let* (
        (ret (cons nil nil)) ; dummy cell trashed at end of processing
        (last-cell ret)
        (test   (if (functionp predicate)
                    predicate
                   (lambda (x) (equal x predicate))
                   )
                )
(ltail (if from-end (reverse (symbol-value lst-var)) (symbol-value lst-var)))
        v
        )
   (while ltail
     (setq v (car ltail)
           ltail (cdr ltail)
           )
     (if (funcall test v)
         (when (if (wholenump remove-count)
                   (> 1 (setq remove-count (1- remove-count)))
                 (null remove-count)
                 )
             (setcdr last-cell ltail)
             (setq ltail nil)
             )
       (setcdr last-cell (cons v nil))
       (setq last-cell (cdr last-cell))
       )
     )
   (setq ret (cdr ret))
   (when from-end (setq ret (reverse ret)))
   (set lst-var ret)
   )
 )
;--------------------- contribution end ------------------------------------------------------------





reply via email to

[Prev in Thread] Current Thread [Next in Thread]