Subject: Re: Counting Nodes From: Brandon Ibach <bibach@xxxxxxxxxxxxxx> Date: Fri, 25 Feb 2000 12:20:04 -0600 |
Quoting Maltby, David G <david.g.maltby@xxxxxxxx>: > With Brandon's theory that non-element class nodes were being included in > the node-list returned by (siblings) proven correct, I have rewritten my > procedure to trap those nodes and not count them. This procedure provides > the functionality I need. > > [...] > > Is there are better or more appropriate element class test of the node then > (gi)? Is there efficiencies to be gained by naming (node-list-first > text-siblings) rather then doing the (node-list-first ) call three times? > Well, you could do: (equal? 'element (node-property 'classnm n)), but I expect that (gi) is just fine, too, at least in this case, and as you can see in Matthias' new code, it allows you to check even more specifically, just in case <text> changes later to allow other elements in its content model. As for calling (node-list-first) three times, you *could* wrap a (let) around your (cond), and do it just once at the top, but I'd guess, offhand, that the three calls aren't really creating that much overhead. > I need to understand mapping a procedure over a list better. > Well, here's a pretty good opportunity, because your procedure and Matthias' are fairly similar in their end result. Let's compare... :) Quoting Matthias Clasen <clasen@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx>: > (define (text-node-cnt #!optional (cur-text-node (current-node))) > (node-list-length > (node-list-filter > (lambda (snl) (and > (equal? (gi snl) "TEXT") > (not (attribute-string "type" snl)))) > (preced cur-text-node)))) > Matthias is using (node-list-filter) here. According to the standard (combining the definitions of node-list-filter and node-list-reduce a bit), (node-list-filter) can be defined as: (define node-list-filter (lambda (proc nl) (let loop ((n nl) (r (empty-node-list))) (cond ((node-list-empty? n) r) ((proc (node-list-first n)) (loop (node-list-rest n) (node-list r (node-list-first n)))) (else (loop (node-list-rest n) r)))))) As you can see, (node-list-filter) just works its way through the node-list, applying the procedure to each node. If the procedure evaluates to true, it adds the node to the result node-list. Or, otherwise put, it removes the nodes for which proc returns false. Now, Matthias also used (preced) to get his node-list, rather than using (siblings). Based on the version in the standard (but stripped down to handle just a singleton node-list argument), (preced) is: (define preced (lambda (snl) (let loop ((scanned (empty-node-list)) (rest (siblings snl))) (cond ((node-list-empty? rest) (empty-node-list)) ((node-list=? snl (node-list-first rest)) scanned) (else (loop (node-list scanned (node-list-first rest)) (node-list-rest rest))))))) Again, we're starting with the node-list from (siblings) and filtering it. If you look closely, you'll see that the first two clauses of the (cond) are essentially the same as the ones in your procedure. So, Matthias just took the shortcut on those and let a built-in function do the work. If you put these two definitions ((preced) and (node-list-filter)) together, along with the procedure that Matthias passed in to (node-list-filter), you should see that it's all basically the same as your own procedure. The difference is, Matthias' code was building a node-list which we would calculate the length of at the end, where your code was just incrementing a counter as it went along. -Brandon :) DSSSList info and archive: http://www.mulberrytech.com/dsssl/dssslist
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: Counting Nodes, Matthias Clasen | Thread | RE: Counting Nodes, Peter Nilsson |
Re: Emulation of XSL's id() in DSSS, Ralf Kempkens | Date | Totally ignorant question, Jan Deininger |
Month |