0
votes

I used map and filter to calculate the length of a certain items in a list of triples in Dr.Racket. I want to return the number of times an item is repeated in my list of triples. However, my code returns the actual length of the triples not the number of times an item is repeated.

 (define (countStatus lst item)
      (map length (filter(lambda (x) (not(equal? x item))) lst)))

 (define lst '((joe  21  “employed”)  ( ann 19 “unemployed”)  (sue 18 “employed” ) ) )

The following procedure should return 2 but instead returns the length of the triples.

> (countStatus lst "employed")
'(3 3 3)
1

1 Answers

1
votes

Consider what the x is in the argument to filter. It's an element of lst, which means its either '(joe 21 "employed"), '(ann 19 "unemployed"), or '(sue 18 "employed").

None of those elemets are equal to item which is "employed". So instead of checking equality with the whole element, you should check equality with the status of the element. Something like this:

;; Example: (get-status '(joe 21 "employed")) = "employed"
(define (get-status x) (third x))

Then the predicate for filtering should check whether the status is equal to the item:

(lambda (x) (equal? (get-status x) item))

Notice how it uses get-status, and how it does not use not around the equality.

After filtering with this predicate, you can use length instead of map length.

;; Example: (get-status '(joe 21 "employed")) = "employed"
(define (get-status x) (third x))

(define (countStatus lst item)
  (length (filter (lambda (x) (equal? (get-status x) item)) lst)))

(define lst '((joe 21 "employed") (ann 19 "unemployed") (sue 18 "employed")))

Under these definitions, you get 2 like you wanted:

> (countStatus lst "employed")
2