Re: Filtering nodes

Subject: Re: Filtering nodes
From: Brandon Ibach <bibach@xxxxxxxxxxxxxx>
Date: Thu, 9 Nov 2000 16:08:06 -0600
Quoting Maltby, David G <david.g.maltby@xxxxxxxx>:
> I would like to write a two node-list-filters, (first-ns nl) and
> (last-ns nl),  such that given the following node-list nl =  (T N N S S S N),
> (first-ns nl) would return (N N) which would be the two nodes following T
> and before S, and (last-ns nl) would return (N) which would be the
> last node in the node-list.
> 
> The content model for the container of these elements would be
> <!element C (T?, N*, S+, N*)>
> 
> It seems some clever use of (node-list-filter) should be able to sort this
> out but I am struggling with the appropriate lambda expression.  Maybe there
> is a better way.  I have looked through section 10.2.3 but perhaps I am not
> seeing the grove for the all the nodes.  Any thoughts?
> 
   Well, I'd go with an approach using (node-list-reduce), which is a
more general tool than (node-list-filter).  In fact, you may have
noticed that the standard defines (n-l-f) in terms of (n-l-r).
   The benefit of (n-l-r) in this case is that it allows us to carry
an arbitrary object through the processing of the node list.  The goal
of (first-ns) could be stated as "return all of the N nodes until we
see an S node":

(define (first-ns nl)
  (node-list-reduce nl (lambda (o n)
                         (let ((s (or (car o) (string=? (gi n) "S"))))
                           (list s (if (and (not s) (string=? (gi n) "N"))
                                       (node-list (cadr o) n) (cadr o)))))
                    (list #f (empty-node-list))))

   Here, we carry a list object containing a boolean and a node list.
The node list is, of course, the result which we are building.  The
boolean tracks whether we have seen an S node yet.  The definition is
similar for (last-ns), whose goal is "return all of the N nodes after
we see an S node":

(define (last-ns nl)
  (node-list-reduce nl (lambda (o n)
                         (let ((s (or (car o) (string=? (gi n) "S"))))
                           (list s (if (and s (string=? (gi n) "N"))
                                       (node-list (cadr o) n) (cadr o)))))
                    (list #f (empty-node-list))))

   In fact, the definitions are identical except for the (not) in
(first-ns), right before the check to see if the current node is an N.
It wouldn't take much to create a single definition, called by both of
these functions, which takes an extra boolean argument to specify
which set of N nodes you want.  Here's a hint:

(define (xor a b) (if (and a b) #f (or a b)))

-Brandon :)


 DSSSList info and archive:  http://www.mulberrytech.com/dsssl/dssslist


Current Thread