mtylerb Posted October 26, 2008 Share Posted October 26, 2008 Can someone explain to me what the parts 1 and 2 (below) of usort refer to? usort($part1, array($part2, function-name)); I have tried looking up examples, but all I get is the same PHP manual example over and over, and they don't explain it very well. Link to comment https://forums.phpfreaks.com/topic/130150-solved-usort-help/ Share on other sites More sharing options...
ratcateme Posted October 26, 2008 Share Posted October 26, 2008 well looking at that it would look for a class with the name of what ever $part2 is and then call classname(from $part2)->function-name see the third example here http://nz.php.net/usort Scott. Link to comment https://forums.phpfreaks.com/topic/130150-solved-usort-help/#findComment-674901 Share on other sites More sharing options...
mtylerb Posted October 26, 2008 Author Share Posted October 26, 2008 Lol, thanks ratcateme, It was that 3rd example I was having problems with. Especially after seeing: usort($children, array($this, 'cmpVals')); So this searches the array $children which is a part of whatever class using function cmpVals? What if $children is an array of objects of type different than the class that we're currently in? $children is currently returning an array of PageArchive Objects. Like so, Array ( [0] => PageArchive Object ( [id] => 68 [title] => Test 3 ) [1] => PageArchive Object ( [id] => 37 [title] => Test 1 ) [2] => PageArchive Object ( [id] => 59 [title] => Test 2 ) [3] => PageArchive Object ( [id] => 72 [title] => Test 4 ) ) I'm wanting to sort the objects by their id's with no need to keep their top level keys. So that it, instead, looks like: Array ( [0] => PageArchive Object ( [id] => 37 [title] => Test 1 ) [1] => PageArchive Object ( [id] => 59 [title] => Test 2 ) [2] => PageArchive Object ( [id] => 68 [title] => Test 3 ) [3] => PageArchive Object ( [id] => 72 [title] => Test 4 ) ) Link to comment https://forums.phpfreaks.com/topic/130150-solved-usort-help/#findComment-674903 Share on other sites More sharing options...
Barand Posted October 26, 2008 Share Posted October 26, 2008 As you are sorting on the first object var, a simple sort() will suffice <?php class page { private $id; private $title; function __construct ($t) { $this->id = rand(1,100); $this->title = $t; } } class book { private $pages; function __construct () { for ($i=0, $t='A'; $i<10; $i++, $t++) { $this->pages[] = new page ($t); } } function showPages () { echo '<pre>', print_r($this->pages, true), '</pre>'; } function sortPages () { sort($this->pages); } } $foo = new book; $foo->showPages(); $foo->sortPages(); $foo->showPages(); ?> Link to comment https://forums.phpfreaks.com/topic/130150-solved-usort-help/#findComment-674906 Share on other sites More sharing options...
mtylerb Posted October 26, 2008 Author Share Posted October 26, 2008 No, I'm not, I'm trying to sort according to $children->$vars where $vars is a choice of what they want to order by. It might be id or it might be a date (created_on) that I eliminated for ease of reading. I have it selecting the right var, but I can't get it to actually sort for me. I'm grabbing 2 separate objects and merging them together, I then need to re-sort the newly merged entries. It's for a plugin to give an RSS feed type searchability to a CMS. Currently they have a find('/articles/archive'); I'm trying to expand that to adv_find(array('/articles/archive1','/articles/archive2')); So the class itself is an extension of the original class, and uses the find() function available. It then merges the 2 (or more) results into one array. The last thing I need to do to complete this is sort and trim. Sort all the newly merged entries by $vars Trim the excess entries created by running 2 (or more) queries. Sorry, I'm trying to explain as best I can. Currently in my class, the search bit looks like: <?php class adv_find extends Page { public $search; public $vars; public $results; public $sortAttribute; public function sort($attribute,$children) { $this->sortAttribute = $attribute; usort($children, array($this, 'cmpVals')); return $this->parentArray; } private function cmpVals($val1, $val2) { $search = $this->sortAttribute; return strcasecmp($val1->$search, $val2->$search); } public function adv_where($search, $vars) { /* Build Variable $children */ $this->sort($sve['0'],$children); return $children; } public function __construct($search,$vars) { // Instantiate all the variables necessary to do the search $this->search = $search; $this->vars = $vars; // Do the search and then save the results to $this->results $this->results = $this->adv_where($this->search,$this->vars); } } function finder($query, $args = '') { $found = new adv_find($query, $args); } ?> I'm definitely no guru, but I'm trying. Link to comment https://forums.phpfreaks.com/topic/130150-solved-usort-help/#findComment-674910 Share on other sites More sharing options...
mtylerb Posted October 26, 2008 Author Share Posted October 26, 2008 If it's useful at all, when I change the function cmpVals() to: <?php private function cmpVals($val1, $val2) { $search = $this->sortAttribute; print_r($val1->$search); echo "<br />"."\r\n"; print_r($val2->$search); echo "<br />"."\r\n"; echo strcasecmp($val1->$search, $val2->$search); echo "<br />"."\r\n"; echo "<br />"."\r\n"; return strcasecmp($val1->$search, $val2->$search); } ?> The values it outputs is: 2008-10-25 20:22:33 2008-10-25 20:18:29 1 2008-10-25 20:22:33 2008-10-25 20:17:49 1 2008-10-25 20:22:51 2008-10-25 20:22:33 2 2008-10-25 20:18:29 2008-10-25 20:17:49 1 Why is there a 2 in there? This is my confused face. Yes, ok, it looks a lot like my everyday face, but still. Link to comment https://forums.phpfreaks.com/topic/130150-solved-usort-help/#findComment-674919 Share on other sites More sharing options...
Barand Posted October 26, 2008 Share Posted October 26, 2008 like this? <?php class page { private $id; private $title; function __construct ($t) { $this->id = rand(1,100); $this->title = $t; } function getVal($v) { return $this->$v; } } class book { private $pages; private $sortby; function __construct () { for ($i=0, $t='A'; $i<10; $i++, $t++) { $this->pages[] = new page ($t); } } function showPages () { echo '<pre>', print_r($this->pages, true), '</pre>'; } function sortPages ($sortby) { $this->sortby = $sortby; usort($this->pages, array($this, 'mycmp')); } function mycmp($a, $b) { $x = $a->getVal($this->sortby); $y = $b->getVal($this->sortby); return strcasecmp($x,$y); } } $foo = new book; $foo->showPages(); $foo->sortPages('id'); $foo->showPages(); $foo->sortPages('title'); $foo->showPages(); ?> Link to comment https://forums.phpfreaks.com/topic/130150-solved-usort-help/#findComment-674920 Share on other sites More sharing options...
mtylerb Posted October 26, 2008 Author Share Posted October 26, 2008 Yes! That's exactly it. How is: <?php function sortPages ($sortby) { $this->sortby = $sortby; usort($this->pages, array($this, 'mycmp')); } function mycmp($a, $b) { $x = $a->getVal($this->sortby); $y = $b->getVal($this->sortby); return strcasecmp($x,$y); } ?> Different from mine? <?php public function sort($attribute,$children) { $this->sortAttribute = $attribute; usort($children, array($this, 'cmpVals')); } private function cmpVals($val1, $val2) { $search = $this->sortAttribute; return strcasecmp($val1->$search, $val2->$search); } ?> Link to comment https://forums.phpfreaks.com/topic/130150-solved-usort-help/#findComment-674921 Share on other sites More sharing options...
Barand Posted October 26, 2008 Share Posted October 26, 2008 Sorry, I was under the impression yours wasn't working so just adapted my first post. The only diff is my class had private vars, so I had to use getVal(). Re the 2, the manual says strcasecmp will return < 0, 0 or > 0, it doesn't have to be -1 or +1. E.G. If you are comparing numeric items, the compare function can just be function mycmp($a, $b) {return $a->something - $b->something;} Link to comment https://forums.phpfreaks.com/topic/130150-solved-usort-help/#findComment-674927 Share on other sites More sharing options...
mtylerb Posted October 26, 2008 Author Share Posted October 26, 2008 Sorry, I was under the impression yours wasn't working so just adapted my first post. It isn't, that's my problem. When I try to sort using my function, the array doesn't change. It stays in it's original form. I tried sorting by title even, which gives a couple -1's: Test Article 4 Test Article 2 2 title Test Article 4 Test Article 1 3 title Test Article 3 Test Article 4 -1 title Test Article 2 Test Article 3 -1 title Test Article 1 Test Article 2 -1 But it still doesn't change the order. usort doesn't have to be saved, it automatically writes re-arranges the variable and it's permanent, correct? Link to comment https://forums.phpfreaks.com/topic/130150-solved-usort-help/#findComment-674930 Share on other sites More sharing options...
Barand Posted October 26, 2008 Share Posted October 26, 2008 usort doesn't have to be saved, it automatically writes re-arranges the variable and it's permanent, correct? Correct, the array is passed by reference so the original array is sorted; it's not just a copy of the array sorted inside the function. Link to comment https://forums.phpfreaks.com/topic/130150-solved-usort-help/#findComment-674935 Share on other sites More sharing options...
mtylerb Posted October 26, 2008 Author Share Posted October 26, 2008 I am completely stumped. I don't know if it's the input then, but assuming my functions (above) *should* work, am I doing something wrong with my input? http://pastebin.com/m4a03e71e <- is the output of $children and what is being put in to be sorted http://pastebin.com/m6ed560e6 <- is the full text of the class and it's following function, though not the class that it is extending. There's a lot of extra print_r's in there to help me find the problem. Link to comment https://forums.phpfreaks.com/topic/130150-solved-usort-help/#findComment-674936 Share on other sites More sharing options...
Barand Posted October 26, 2008 Share Posted October 26, 2008 public function adv_where($search, $vars) { /* Build Variable $children */ $this->sort($sve['0'],$children); return $children; } should that be $this->sort($sve['0'],$this->children); Link to comment https://forums.phpfreaks.com/topic/130150-solved-usort-help/#findComment-674941 Share on other sites More sharing options...
mtylerb Posted October 26, 2008 Author Share Posted October 26, 2008 No, $children is created by the function and was meant to be disposable, I wanted to keep as few class variables as possible. You can see the creation in: http://pastebin.com/m6ed560e6 Link to comment https://forums.phpfreaks.com/topic/130150-solved-usort-help/#findComment-674942 Share on other sites More sharing options...
Barand Posted October 26, 2008 Share Posted October 26, 2008 you pass a copy of $children to sorty() Then you copy $children to $this->children and sort that copy. EDITED in red Link to comment https://forums.phpfreaks.com/topic/130150-solved-usort-help/#findComment-674943 Share on other sites More sharing options...
mtylerb Posted October 26, 2008 Author Share Posted October 26, 2008 you pass $children to sorty() Then you copy $children to $this->children and sort that copy. Right, that's what I'm doing at the moment. That wasn't originally in there, I'm just trying anything and everything grasping at straws, hoping one of them won't be the short one. I just can't understand why strcasecmp is evaluating them correctly, but usort isn't organizing them. Could it be because the PageArchive Object was created by another class? Do I need to do something with the usort function? usort($children, array($this, 'cmpVals') I'm still not sure what $this refers to or what it does to the usort function. I have changed that to adv_find and tried Page (the class that adv_find extends) and PageArchive (the type of object), with no luck. Link to comment https://forums.phpfreaks.com/topic/130150-solved-usort-help/#findComment-674946 Share on other sites More sharing options...
Barand Posted October 26, 2008 Share Posted October 26, 2008 try changing sorty() so children is passed by ref public function sorty($attribute, &$children) { $this->sortAttribute = $attribute; usort($children, array($this, 'cmpVals')); } Link to comment https://forums.phpfreaks.com/topic/130150-solved-usort-help/#findComment-674947 Share on other sites More sharing options...
mtylerb Posted October 26, 2008 Author Share Posted October 26, 2008 Nope, still does nothing. I really appreciate the help, any other ideas? Can you explain what $this in: usort($children, array($this, 'cmpVals')); Does? What does it refer to? What changes if I change it? Link to comment https://forums.phpfreaks.com/topic/130150-solved-usort-help/#findComment-674951 Share on other sites More sharing options...
mtylerb Posted October 26, 2008 Author Share Posted October 26, 2008 I've been up far too long, perhaps I'll see more after a good morning's sleep? Thanks for all the help Barand, if you have any further ideas, I'll be checking back here later, and I'll be sure to try them out. Same for anyone else, if you have any ideas, I'd love to hear and try them out. Thanks in advance! Link to comment https://forums.phpfreaks.com/topic/130150-solved-usort-help/#findComment-674953 Share on other sites More sharing options...
Barand Posted October 26, 2008 Share Posted October 26, 2008 $this refers to the current object array ($this, 'cmpVals') refers to the the current object's class's "cmpVals" method. so it tells usort() to use that particular function/method when comparing values. But I am sure I am sure you problem lies in sorting a copy of the children array rather than the original, which is why the original always remains unchanged. In my code the array to be sorted was a class var and therefore the same array is available to all the methods. You use $children which is local to the method, which is why I advised passing by ref so all functions use the same instance of the array Link to comment https://forums.phpfreaks.com/topic/130150-solved-usort-help/#findComment-674954 Share on other sites More sharing options...
mtylerb Posted October 26, 2008 Author Share Posted October 26, 2008 Barand, you are awesome! I finally understood what you were trying to say, I added in the $this->children variable and only passed that around and it works perfectly! Thanks so much and all the best to you! Link to comment https://forums.phpfreaks.com/topic/130150-solved-usort-help/#findComment-675172 Share on other sites More sharing options...
Barand Posted October 26, 2008 Share Posted October 26, 2008 ... I added in the $this->children variable and only passed that around ... if you are using $this->children it shouldn't need "passing around". You can just access it from each of the class methods. Link to comment https://forums.phpfreaks.com/topic/130150-solved-usort-help/#findComment-675250 Share on other sites More sharing options...
mtylerb Posted October 26, 2008 Author Share Posted October 26, 2008 Lol, yeah, I meant pass the "word" around, not the data contained within. I thank you for your persistence, you were a great help! Link to comment https://forums.phpfreaks.com/topic/130150-solved-usort-help/#findComment-675254 Share on other sites More sharing options...
Recommended Posts
Archived
This topic is now archived and is closed to further replies.