The keyword approach can create an annoying collection of keywords, although it's easy enough as it's a common operation.

Another approach is to define a macro around each map function that does collecting of the output...

(map-index-collecting #'my-fn :value 5)
=>
(let (result)
  (flet ((collector (k v pk)
           (push (funcall #'my-fn k v pk) result)))
    (declare (dynamic-extent collector))
    (map-index (lambda (k v pk) (push (funcall collect-fn k v pk))
               :value 5))
  (nreverse result))

Or a shortcut for inline lambda expressions...

(map-index-collecting (lambda (k v pk) k) :value 5)
=>
(let (result)
  (map-index (lambda (k v pk) (push (progn k) result)) :value 5)
  (nreverse result))

The get-instance-by-xxx functions are a specialized version of map- index-collecting except they only collect values and only work on class indices. We could use that approach and do the various operations after we've built the list instead of while...

So the options are:

macro wrappers
(map-index-collecting #'my-fn :value 5)
(map-index-collecting (lambda (k v pk) k) :value 5)

vs.

keyword option
(map-index #'my-fn :value 5 :collect t)
(map-index (lambda (k v pk) k) :value 5 :collect t)

vs

list-oriented extractors
(mapcar #'my-fn
        (get-index-elements :value 5))
(get-index-elements :value 5)

Anyone have any preferences?

Ian


On Apr 22, 2007, at 6:44 PM, Joe Corneli wrote:


In the discussion of how to build a "virtual subtree",

http://common-lisp.net/pipermail/elephant-devel/2007-April/000949.htm

Ian gave me a tip on how to find all Triples with a certain property:

   [My recipe] will create an index 'triples-first which only indexes
   triples and does so by the value of the first element.  Thus you
   can easily retrieve all triples with the first element eq to 5.

   ELE-TESTS> (map-index (lambda (sk v pk) (print v)) (get-index my-
   things 'triples-first :value 5)))

Just wanted to point out that I want to *collect* these values -- so I
wrote a function that does this:

(defun match-triples-beginning (beginning)
  (let ((results (list nil)))
    (map-index (lambda (k v pk)
                 (declare (ignore k pk))
                 (setq results (nconc results (list v))))
               (get-index *things* 'triples-beginning)
               :value beginning)
    (cdr results)))

This makes me think that it would be nice to have a `mapcar'-style
function built in for mapping across an index and collecting the
results.  First question is, what would such a function be called!
(Maybe just add a :collect keyword to `map-index'?)
_______________________________________________
elephant-devel site list
elephant-devel@common-lisp.net
http://common-lisp.net/mailman/listinfo/elephant-devel

_______________________________________________
elephant-devel site list
elephant-devel@common-lisp.net
http://common-lisp.net/mailman/listinfo/elephant-devel

Reply via email to