Coding Geniuses: Answer this Question Please (best answer gets $20) - El Forum - 03-19-2008
[eluser]danoph[/eluser]
I have an array of website pages that I want to sort. Right now, it is a one-dimensional array that I need to sort into a multi-dimensional array. Pages that have a "parent_thread" will need to fall under their appropriate parent thread in the array. A page can have an unlimited number of children pages. Here is the flat array:
Code: Array
(
[1] => stdClass Object
(
[id] => 1
[parent_thread] =>
[title] => Moneypete
[permalink] => home
)
[2] => stdClass Object
(
[id] => 2
[parent_thread] => 1
[title] => Entrepreneurship
[permalink] => entrepreneurship
)
[3] => stdClass Object
(
[id] => 3
[parent_thread] => 2
[title] => Ideas, Business Advices, and Franchises
[permalink] => ideas_business_advice_franchises
)
[4] => stdClass Object
(
[id] => 4
[parent_thread] => 2
[title] => Practical help for Entrepreneur Startups
[permalink] => practical-help-for-entrepreneur-startups
)
[5] => stdClass Object
(
[id] => 5
[parent_thread] => 2
[title] => Management & Leadership
[permalink] => management_leadership
)
[6] => stdClass Object
(
[id] => 6
[parent_thread] => 1
[title] => Real Estate
[permalink] => real_estate
)
[7] => stdClass Object
(
[id] => 7
[parent_thread] => 1
[title] => Stocks & Bonds
[permalink] => stocks_bonds
)
[8] => stdClass Object
(
[id] => 8
[parent_thread] => 1
[title] => Financial Education
[permalink] => financial_education
)
[9] => stdClass Object
(
[id] => 9
[parent_thread] => 1
[title] => Residential
[permalink] => residential
)
[12] => stdClass Object
(
[id] => 12
[parent_thread] => 1
[title] => Commercial
[permalink] => commercial
)
[15] => stdClass Object
(
[id] => 15
[parent_thread] => 1
[title] => E-Commerce
[permalink] => ecommerce
)
[16] => stdClass Object
(
[id] => 16
[parent_thread] => 15
[title] => Videos
[permalink] => videos
)
}
I need to turn that array into :
Code: Array
(
[home] => stdClass Object
(
[id] => 1
[parent_thread] =>
[title] => Moneypete
[permalink] => home
[children] => Array
(
[entrepreneurship] => stdClass Object
(
[id] => 2
[parent_thread] => 1
[title] => Entrepreneurship
[permalink] => entrepreneurship
[children] => Array
(
[ideas_business_advice_franchises] => stdClass Object
(
[id] => 3
[parent_thread] => 2
[title] => Ideas, Business Advices, and Franchises
[permalink] => ideas_business_advice_franchises
)
)
[ecommerce] => stdClass Object
(
[id] => 15
[parent_thread] => 1
[title] => E-Commerce
[permalink] => ecommerce
)
)
etc...
I need one sorting function to take the array and sort them into a structured site map in the format above.
Deadline: Thursday, March 20, 3pm CST.
It's been a while since I've had to tackle these kinds of algorithms, so the best answer will get 20 credits ($20) to http://graphicleftovers.com to buy logos and graphics and stuff. Thanks!
Coding Geniuses: Answer this Question Please (best answer gets $20) - El Forum - 03-19-2008
[eluser]dtrenz[/eluser]
I couldn't resist...
As I was doing this I realized that the "id" property is redundant if you have a numeric array whose keys match the ids. So I did it with, and without ids.
DISCLAIMER: I'm sure there are many better and more clever ways, but in an hour, this is what I came up with (including an infinite recursion by reference headache).
First, here it is to spec (with ids):
Code: class Page
{
public $id;
public $parent_thread;
public $title;
public $permalink;
public $children;
public function __construct($id = 0, $parent_thread = NULL, $title = '', $permalink = '', $children = array())
{
$this->id = $id;
$this->parent_thread = $parent_thread;
$this->title = $title;
$this->permalink = $permalink;
$this->children = $children;
}
}
$page_array = array(
1 => new Page(1, NULL, 'Moneypete', 'home'),
2 => new Page(2, 1, 'Entrepreneurship','entrepreneurship'),
3 => new Page(3, 2, 'Ideas, Business Advices, and Franchises','ideas_business_advice_franchises'),
4 => new Page(4, 2, 'Practical help for Entrepreneur Startups','practical-help-for-entrepreneur-startups'),
5 => new Page(5, 2, 'Management & Leadership','management_leadership'),
6 => new Page(6, 1, 'Real Estate','real_estate'),
7 => new Page(7, 1, 'Stocks & Bonds','stocks_bonds'),
8 => new Page(8, 1, 'Financial Education','financial_education'),
9 => new Page(9, 1, 'Residential','residential'),
12 => new Page(12, 1, 'Commercial','commercial'),
15 => new Page(15, 1, 'E-Commerce','ecommerce'),
16 => new Page(16, 15, 'Videos','videos')
);
print_r($page_array);
foreach ($page_array as $page)
{
if (!isset($page->parent_thread))
{
$new_page_array = array($page->permalink => $page);
}
else
{
$parent_thread = $page->parent_thread;
$level_map = array($parent_thread);
while (isset($page_array[$parent_thread]->parent_thread))
{
$parent_thread = $page_array[$parent_thread]->parent_thread;
$level_map[] = $parent_thread;
}
$level_map = array_reverse($level_map);
$parent_array =& $new_page_array[$page_array[array_shift($level_map)]->permalink];
if (!empty($level_map))
{
foreach ($level_map as $level)
{
$parent_array =& $parent_array->children[$page_array[$level]->permalink];
}
}
$parent_array->children[$page->permalink] = $page;
}
}
print_r($new_page_array);
...and here it is w/o ids:
Code: class Page
{
public $parent_thread;
public $title;
public $permalink;
public $children;
public function __construct($parent_thread = NULL, $title = '', $permalink = '', $children = array())
{
$this->parent_thread = $parent_thread;
$this->title = $title;
$this->permalink = $permalink;
$this->children = $children;
}
}
$page_array = array(
1 => new Page(NULL, 'Moneypete', 'home'),
2 => new Page(1, 'Entrepreneurship','entrepreneurship'),
3 => new Page(2, 'Ideas, Business Advices, and Franchises','ideas_business_advice_franchises'),
4 => new Page(2, 'Practical help for Entrepreneur Startups','practical-help-for-entrepreneur-startups'),
5 => new Page(2, 'Management & Leadership','management_leadership'),
6 => new Page(1, 'Real Estate','real_estate'),
7 => new Page(1, 'Stocks & Bonds','stocks_bonds'),
8 => new Page(1, 'Financial Education','financial_education'),
9 => new Page(1, 'Residential','residential'),
12 => new Page(1, 'Commercial','commercial'),
15 => new Page(1, 'E-Commerce','ecommerce'),
16 => new Page(15, 'Videos','videos')
);
print_r($page_array);
foreach ($page_array as $page)
{
if (!isset($page->parent_thread))
{
$new_page_array = array($page->permalink => $page);
}
else
{
$parent_thread = $page->parent_thread;
$level_map = array($parent_thread);
while (isset($page_array[$parent_thread]->parent_thread))
{
$parent_thread = $page_array[$parent_thread]->parent_thread;
$level_map[] = $parent_thread;
}
$level_map = array_reverse($level_map);
$parent_array =& $new_page_array[$page_array[array_shift($level_map)]->permalink];
if (!empty($level_map))
{
foreach ($level_map as $level)
{
$parent_array =& $parent_array->children[$page_array[$level]->permalink];
}
}
$parent_array->children[$page->permalink] = $page;
}
}
print_r($new_page_array);
it's all done in the main foreach loop. you can toss it in a function easy enough.
don't worry about the $20 credit...
hope this works for you.
Coding Geniuses: Answer this Question Please (best answer gets $20) - El Forum - 03-19-2008
[eluser]danoph[/eluser]
Wow, I'm impressed. Worked perfectly!
You are good. Thanks for your help!
If you ever want the credits, just e-mail me info [at] bizwidgets.biz
Thanks again
Coding Geniuses: Answer this Question Please (best answer gets $20) - El Forum - 03-19-2008
[eluser]Derek Allard[/eluser]
SEE! Now THIS is why the CI community kicks ass. Super technical post asking for help, and within hours a super complex solution is presented, and as evidenced by dtrenz's asking for no money, it was obvious he did it just to help out a fellow CI-er, and/or for challenge.
dtrenz, my hats off, this just made my day - on behalf of all of CI, thanks
Coding Geniuses: Answer this Question Please (best answer gets $20) - El Forum - 03-19-2008
[eluser]Pygon[/eluser]
For fun (and not for money), I think I'll take a stab at this tomorrow.
Coding Geniuses: Answer this Question Please (best answer gets $20) - El Forum - 03-19-2008
[eluser]danoph[/eluser]
Thanks for the help everyone. In case this may help someone, I figured out the easy part! I came up with a simple function to recursively iterate through the new pages array generated by dtrenz' function and print out the pages in a structured format:
Code: function print_sitemap($pages, $level=0) {
$return = '';
foreach ($pages as $id => $page) {
$return .= str_repeat(' ', 4*$level);
$return .= '- '.$page->title.'<br />';
if (!empty($page->children)) $return .= $this->print_sitemap($page->children, ($level+1));
}
return $return;
}
This generates:
Code: Moneypete
- Entrepreneurship
- Ideas, Business Advices, and Franchises
- Practical help for Entrepreneur Startups
- Management & Leadership
- Real Estate
- Stocks & Bonds
- Financial Education
- Residential
- Commercial
- E-Commerce
- Videos
Coding Geniuses: Answer this Question Please (best answer gets $20) - El Forum - 03-20-2008
[eluser]dtrenz[/eluser]
Glad I could help.
Anyone interested in giving me a little instant karma by helping me with my CI problem?
edit: fixed, thanks derek j & xwero
Coding Geniuses: Answer this Question Please (best answer gets $20) - El Forum - 03-20-2008
[eluser]danoph[/eluser]
Seems like you solved the problem before I could even take a look!
@dtrenz: I am using your code in my CI CMS system. It includes an interactive site map, that you built.
@everyone: The CMS is going to have some object relational stuff like RoR does. More objected oriented! I'm going to release it very soon, I hope.
Thanks!
Coding Geniuses: Answer this Question Please (best answer gets $20) - El Forum - 03-20-2008
[eluser]Frank Rocco[/eluser]
dtrenz - very nice job.
I looked at it until my head hurt.<g>
Frank
Coding Geniuses: Answer this Question Please (best answer gets $20) - El Forum - 03-20-2008
[eluser]dtrenz[/eluser]
Heh, my head hurt quite a bit. I think I even went cross-eyed a few times. It's hard to step-through code like that in your head. I wish there was a PHP debugger with breakpoints and watch windows...
|