From: Lowell
Subject: Counting occurences of an item in a list: is there a better way?
Date:
Message-ID: <bk3kgk$9s$1@mughi.cs.ubc.ca>
To count the occurences of the number h in a list, I have the following:
(let ((result 0))
(loop for i in finals
do (when (= i h)
(incf result)))
result))
Is there already something built in to CL that does something similar?
Or is there a better (or more abstract) way I should be doing this?
--
Lowell
From: Peter Seibel
Subject: Re: Counting occurences of an item in a list: is there a better way?
Date:
Message-ID: <m3ad96bmcy.fsf@javamonkey.com>
Lowell <······@cs.ubc.ca> writes:
> To count the occurences of the number h in a list, I have the following:
>
> (let ((result 0))
> (loop for i in finals
> do (when (= i h)
> (incf result)))
> result))
>
> Is there already something built in to CL that does something similar?
> Or is there a better (or more abstract) way I should be doing this?
(count h finals :test #'=)
Or if you really want to use loop (as you might if you wanted to count
more than one thing at a time) you can write:
(loop for i in finals counting (= i h))
As an example of counting more than one thing at a time you might write something like:
(loop for i in finals
counting (= i h1) into h1s
counting (= i h2) into h2s
finally (return (list h1s h2s)))
-Peter
--
Peter Seibel ·····@javamonkey.com
Lisp is the red pill. -- John Fraser, comp.lang.lisp
From: Jock Cooper
Subject: Re: Counting occurences of an item in a list: is there a better way?
Date:
Message-ID: <m365ju2cb1.fsf@jcooper02.sagepub.com>
Peter Seibel <·····@javamonkey.com> writes:
> Lowell <······@cs.ubc.ca> writes:
>
> > To count the occurences of the number h in a list, I have the following:
> >
> > (let ((result 0))
> > (loop for i in finals
> > do (when (= i h)
> > (incf result)))
> > result))
> >
> > Is there already something built in to CL that does something similar?
> > Or is there a better (or more abstract) way I should be doing this?
>
> (count h finals :test #'=)
>
> Or if you really want to use loop (as you might if you wanted to count
> more than one thing at a time) you can write:
>
> (loop for i in finals counting (= i h))
>
> As an example of counting more than one thing at a time you might write
>something like:
>
> (loop for i in finals
> counting (= i h1) into h1s
> counting (= i h2) into h2s
> finally (return (list h1s h2s)))
>
Ob Recursive version:
(labels ((r-count (list count)
(if list
(r-count (cdr list) (if (= (car list) test-value)
(1+ count)
count))
count)))
(r-count <the-list> 0))
using appropriate test function and value
Jock Cooper wrote:
> Ob Recursive version:
>
> (labels ((r-count (list count)
> (if list
> (r-count (cdr list) (if (= (car list) test-value)
> (1+ count)
> count))
> count)))
> (r-count <the-list> 0))
>
> using appropriate test function and value
In that case, we need the ObRecursionAbstractedOut version:
(reduce
(lambda (count x)
(if (= x test-value) (1+ count) count))
<the-list>
:initial-value 0)
From: Mark Hurd
Subject: Re: Counting occurences of an item in a list: is there a better way?
Date:
Message-ID: <3f68826f_1@news.iprimus.com.au>
Anton van Straaten wrote:
> Jock Cooper wrote:
> > Ob Recursive version:
> >
> > (labels ((r-count (list count)
> > (if list
> > (r-count (cdr list) (if (= (car list) test-value)
> > (1+ count)
> > count))
> > count)))
> > (r-count <the-list> 0))
> >
> > using appropriate test function and value
>
> In that case, we need the ObRecursionAbstractedOut version:
>
> (reduce
> (lambda (count x)
> (if (= x test-value) (1+ count) count))
> <the-list>
> :initial-value 0)
Which leads to:
(reduce + (mapcar
(lambda (x)
(if (= x test-value) 1 0))
<the-list>
:initial-value 0)
[Or:
(apply + (cons 0 (mapcar
(lambda (x)
(if (= x test-value) 1 0))
<the-list>)))
]
But this is just a filter:
(reduce + (mapcan
(lambda (x)
(when (= x test-value) '(1))
<the-list>)
:initial-value 0)
Or
(let ((count 0))
(mapc
(lambda (x)
(when (= x test-value)
(++ count))
<the-list>)
count)
Which leads to the other loops suggested earlier in this thread.
--
Regards,
Mark Hurd, B.Sc.(Ma.) (Hons.)
PS I use DotLisp regularly which has a syntax with some extraneous brackets
removed and much of CL not present, so if I've not successfully made the above
valid CL, please don't flame me too much. I have tried to get it right, except
I haven't used #' anywhere because the previous post didn't... oh, and it
hasn't been tested...
From: Lowell
Subject: Re: Counting occurences of an item in a list: is there a better way?
Date:
Message-ID: <bk5nlh$bqj$1@mughi.cs.ubc.ca>
Thanks. That's exactly what I was looking for :-)
Peter Seibel wrote:
> Lowell <······@cs.ubc.ca> writes:
>
>
>>To count the occurences of the number h in a list, I have the following:
>>
>>(let ((result 0))
>> (loop for i in finals
>> do (when (= i h)
>> (incf result)))
>> result))
>>
>>Is there already something built in to CL that does something similar?
>>Or is there a better (or more abstract) way I should be doing this?
>
>
> (count h finals :test #'=)
>
> Or if you really want to use loop (as you might if you wanted to count
> more than one thing at a time) you can write:
>
> (loop for i in finals counting (= i h))
>
> As an example of counting more than one thing at a time you might write something like:
>
> (loop for i in finals
> counting (= i h1) into h1s
> counting (= i h2) into h2s
> finally (return (list h1s h2s)))
>
> -Peter
>