Francisco Peters
Francisco Peters

Reputation: 697

Variable to count a certain type of objects in a list (Racket)

I have this code:

(define (countHearts cards)
  (let* ([count 0])
    (map (λ(x)
           (match x
             [(hearts number) (add1 count)]
             [_ #f])) cards))
  count)

Where cards is a list of elements in this format "(hearts number)" And when I use:

(countHearts '( (hearts 1) (hearts 2)))

It returns (the answer should be 2):

#<procedure:count>

All I want is that my code counts the number of "(heart number)" (a type previously defined) that I have in a list, but I keep getting that answer. Does anybody have an idea? I have tried other options besides add1 like

!set count (+ count 1)

But the result is the same.

Upvotes: 0

Views: 152

Answers (2)

uselpa
uselpa

Reputation: 18917

why your code doesn't work

  1. (add1 count) adds 1 to count but throws the result away; you need to set! count to the result of (add1 count)
  2. You had a closing parenthesis too many so your variable count got out of scope and you returned the build-in procedure count - count needs to be returned inside the let* or let expression (I use let since that's sufficient here)
  3. FWIW, both your and @soegaard's code don't work for me and return "match: syntax error in pattern"; I modified the match expression to (list 'hearts _)

So the code becomes:

(define (countHearts cards)
  (let ([count 0])
    (map (λ(x)
           (match x
             [(list 'hearts _) (set! count (add1 count))]
             [_ #f]))
         cards)
    count))

then

> (countHearts '((hearts 1) (hearts 2)))
2

alternative

You could use the build-in count procedure:

(define (countHearts cards)
  (count (lambda (e) (eq? (car e) 'hearts)) 
         cards))

Upvotes: 1

soegaard
soegaard

Reputation: 31147

Try:

(define (count-hearts cards)
  (for/sum ([card cards])
    (match card
      [(list 'hearts n) 1]
      [_                0])))

Upvotes: 2

Related Questions