* (Mirko.Vukovic @ gmail.com) Wrote on Wed, 23 Jan 2008 08:41:15 -0800 (PST): | Second, I was not clear in my original post, but Ken caught it: I am
| parsing an ordered list.
[...]
| (defun collect-duplicates (list)
| (loop
| for a in list
| for b in (cdr list)
| when (equal a b)
| collect b))
|
| It eliminates the (setf ...), and I must admit, the setf just did not
| look right in the loop. But I could not think of another way of doing
| it.
Note that you can use LOOP destructuring like this:
(loop for (a b) on list when (equal a b) collect b)
To fix the duplicate elements in the returned list, you can use
an extra loop variable like this.
(defun collect-duplicates (list)
"LIST is an ordered list without null elements."
(loop for prev = NIL then a
for (a b) on list
when (equal a b) unless (equal prev a) collect a))
* (Mirko.Vukovic @ gmail.com) Wrote on Wed, 23 Jan 2008 08:41:15 -0800 (PST):
Second, I was not clear in my original post, but Ken caught it: I am[...]
parsing an ordered list.
(defun collect-duplicates (list)
(loop
for a in list
for b in (cdr list)
when (equal a b)
collect b))
It eliminates the (setf ...), and I must admit, the setf just did not
look right in the loop. But I could not think of another way of doing
it.
Note that you can use LOOP destructuring like this:
(loop for (a b) on list when (equal a b) collect b)
To fix the duplicate elements in the returned list, you can use
an extra loop variable like this.
(defun collect-duplicates (list)
"LIST is an ordered list without null elements."
(loop for prev = NIL then a
for (a b) on list
when (equal a b) unless (equal prev a) collect a))
(use srfi-1) ;; span for Gauche Scheme
or
(require srfi/1) ;; span for Racket
(require srfi/26) ;; cut for Racket
(define (dups xs)
(if (null? xs)
'()
(let-values (((a b) (span (cut equal? <> (car xs)) xs)))
(if (pair? (cdr a))
(cons (car a) (dups b))
(dups b)))))
(dups '(a a a b c c c d d d d d))
===>
(a c d)
[email protected] wrote:
Hi,
I am still in a bit of shock that my first loop attempt works, with
one legalistic exception.
This is my simple code to show duplicates in a list:
(defun show-duplicates (list)
(loop
initially with ref = (first list)
That is a blank initially clause. CLisp is being nice and coping with
that and pretending you just wrote (loop with ref = (first list)....
for entry in (rest list) do
(if (equal ref entry)
(print entry))
Using when when when is suitable makes code more readable.
(setf ref entry)))
Loop is pretty powerful so you should have a nervous feeling when you
find yourself setfing key iteration variables.
It looks as if you are assuming a sorted list and simply printing out elements the same as the preceding element:
(loop for (a b) on list
when (eql a b)
do (print b))
You get an extra iteration on the last element and nil so an input list
of '(nil nil) would print an extra duplicate. If that is a problem you can:
(loop for a in list
for b in (cdr list) ; this will run out first and halt the loop
when (eql a b)
do (print b))
| Sysop: | Keyop |
|---|---|
| Location: | Huddersfield, West Yorkshire, UK |
| Users: | 715 |
| Nodes: | 16 (0 / 16) |
| Uptime: | 167:35:29 |
| Calls: | 12,096 |
| Calls today: | 4 |
| Files: | 15,003 |
| Messages: | 6,517,813 |