The SitePoint Forums have moved.

You can now find them here.
This forum is now closed to new posts, but you can browse existing content.
You can find out more information about the move and how to open a new account (if necessary) here.
If you get stuck you can get support by emailing forums@sitepoint.com

If this is your first visit, be sure to
check out the FAQ by clicking the
link above. You may have to register
before you can post: click the register link above to proceed. To start viewing messages,
select the forum that you want to visit from the selection below.

Adjacent List Navigator, anyone?

Wondering if anyone has a class/classes for navigating thru an adjacent list set. I'm looking for something that will let me go thru the items as a list, and each item would have methods like, hasChildren(), isFirstChild(), isLastChild() and properties like parent, children, id, parent_id etc.

Also be interested in seeing/hearing about ideas on an interface for something like this.

Remember though, that when you refer to a child it's not the Composite that you are looking at it's self, but it's parent Composite instead, in regards to firstChild and lastChild class methods, so you need to reference a particular Composites parent, ie

You therefore need to pass the ID search into Body::isFirstChild( $id ); to verify that the SearchBox Composite actually is the first child of the Body Composite, or not. So, there are two approaches to how you tackle it, which one are you in favour of?

The first approach, via the parent is more flexible in my view... If your not sure what I'm talking about, I can explain some more...

My datasource is the standard result set from a database:
indexed array/list where each item is an associative array. Each item with an "id" and a "parent_id" key/value.

I was using an iterator at first but I want to stay generic (array) just to get started. I'd like to be able to just pass in the array to the object, have the object build a new list where each item is a "AdjacentListItem". The new list would be ordered to where it follows the id/parent_id relationship as a list. The list items would then have references to the other items. I'd like to have "dumb" items in the list that are really there as place holders for the start of a new list, and the end of a list.

I'd like to have "dumb" items in the list that are really there as place holders for the start of a new list, and the end of a list.

Why would you want to complicate matters? What I mean, is that I would use a Visitor in relation to your problem, so it's the visitor doing the visiting of each node, that would open up your functionality; In knowing that therefore, if you want to have your markers, why not just implement a more specific visitor for that given node(s) in question?

So, you'd have your plain vanilla Visitor, and you'd have a Visitor for your start of list, and another one for the end of list, the last two respectively deal with their own functionality as you require; It's just a case of making sure that you have the proper Visitor do the visiting, on a per node basis.

That is so cool about the Visitor in my view... It doesn't care what node it is in regards of it's use with the Composite pattern

That way, you don't need to do anything special to any nodes to let your scripts know about markers, etc; Remember that with the Composite, all child nodes themselves represent a whole, so I wouldn't like to hinge a bet that you could cleanly, implement what you want anyways, with the Composite...

As the start and end marker nodes wouldn't comply with the other children, and their parents?

OK I know what the Visitor does but honestly haven't used it that much. Would you mind giving me an example or an idea of how the "client" code would look? How do you have more than one visitor for an iteration? A collection of visitors? How would one visitor know what the next and previous items were. Obviously the more I think about it the more confused I am!

OK, here's what I have. I'd love to hear about how I can improve this. Some of this was taken from the Sitepoint PHP Anthology books. Also, I'd love to know what does and doesn't look right in terms of OOP.

This is more like what I use for nested sets, it relies on the fact that things are in right display order, and using the relative levels of previous and current item to work out wether the current item is a new child (hence requiring <ul>) or wether the item is a sibling ($delta = 0) or wether the current item is further up the tree, and requires 1 or more closing </ul></li>s.

/*
Go through all of the root elements
Sets the is_current variable if it matches
Sets the number for the item
Appends it's children if any
*/
function _build () {
$number = 0;
foreach($this->items as $item_data) {
$item =& new AdjacentListItem($item_data);

That was fast! I re-wrote your code for PHP4, it works great. Really nice job! Where did you get the idea for this (composition, interface etc.) ? Why can't I ever be this clever?
...

Go ahead and use it! I am happy that someone actually really does. The idea of algorithm for building nested list (buildTree) is really old and I first made it for some CMS document tree. Writer interface is a stolen idea from lastcraft's SimpleTest *Reporter/Scorer classes