Reputation: 14413
(defun find-attr (node attr)
(let ((children (pt-children node)))
(if (null children)
nil
(let ((subchildren (mapcar ##############
(get-value-if-attrib-present (node attrib) ...)
pt
is a class. (pt-children node)
yields children of node
which are also pt
objects. attr
is a string. suppossing I write get-value-if-attrib-present
to return the value of a pt
object if it has the matching attr
, how do i go about getting the list of all the values of subchildren of node
with matching attr
here (at ####....)?
Upvotes: 1
Views: 355
Reputation: 58560
mapping approach:
;; assuming get-value-if-attrib-present simply returns nil when not present
;; (i.e. your attribute value cannot be nil without ambiguity)
;;
;; get the list of values from the children, matching attrib
;;
(mapcan (lambda (child)
(if (get-value-if-attrib-present child attrib)
(list child)))
children)
mapcan
expects the function to return lists, and it destructively catenates them. So you have to be careful not to return quoted lists from the lambda, or any lists that came from somewhere else (not consed up here).
In Paradigms of Artificial Intelligence Programming (a.k.a PAIP), Peter Norvig introduces a mappend
function which does the same thing, but nondestructively. That's useful to have in your toolkit sometimes.
Upvotes: 1
Reputation: 139251
For Common Lisp use one of these functions:
REMOVE-IF
REMOVE-IF-NOT
REMOVE
They go over a list and remove items. Keep those which you want.
Other wise LOOP
will do it:
(LOOP for item in some-list
when (predicate-p item)
collect it)
IT
is a LOOP
feature -> it refers to the value returned by the predicate in the WHEN
clause.
Upvotes: 1