Jump to content

[SOLVED] Sorting Objects with unknown


mtylerb

Recommended Posts

I can't see why this wouldn't be possible, so here goes:

 

I want to sort an array of PageArchive objects.  It is for a CMS framework.  Anyway, I don't necessarily know which item inside the object the user wants to sort by.

 

I've pasted the output of the variable I want to sort at: http://pastebin.com/m4a03e71e

 

The user will pass on which item he wants to sort with $var.  How would I go about comparing the, for example assuming $var is 'created_on', $output->$var?  I only want to compare the top level objects, not the ones listed under $output->parent;

 

Obviously that doesn't work, but is there a way to make something like that work?  Maybe I'm off my rocker?  Thanks if you're able to help out.

Link to comment
https://forums.phpfreaks.com/topic/130143-solved-sorting-objects-with-unknown/
Share on other sites

Do you mean something like

 

<?php
class Test {
private $someArray = array();

public function add($value) {
	$this->someArray[] = $value;
}

public function sort($attribute) {
	usort($this->$attribute, 'strnatcasecmp');
	return $this->$attribute;
}
}

$test = new Test();
$test->add('something');
$test->add('somethingelse');
$test->add('a third thing');
print_r($test->sort('someArray'));
?>

 

that? if not, you'll have to elaborate. I couldn't make heads or tails of that pastebin thing. Also, you could just use sort() above instead of usort. I just used it so I can change it to be what you really want it to be once you elaborate on your requirements :)

Hmm, that worked on my localhost test.  Perhaps you could be so kind as to tell me where I could find more valid second arguments for usort?  I'm starting to think that's my problem.

 

I thought the second argument had to refer to a function that, I assumed, I had to create?  Anyway, you straightened me out on the reference thing.  I didn't think I could reference:

 

$this->created_on

 

by:

 

$var = 'created_on';

$this->$var

 

Is that all correct?

I went and experimented with your function and it's not quite what I was looking for, hopefully I can better explain:

 

<?php
class Test {

public $someArray = array();
public $someArray2 = array();

public function add($value) {
	$this->someArray[] = $value;
	$this->someArray2[] = $value." added";
}

public function sort($attribute) {
	usort($this->$attribute, 'strnatcasecmp');
	return $this->$attribute;
}
}

$test = new Test();
$test->add('something');
$test->add('somethingelse');
$test->add('a third thing');
print_r($test->sort('someArray'));
print_r($test);
?>

 

Produces the output:

 

Array
(
    [0] => a third thing
    [1] => something
    [2] => somethingelse
)
Test Object
(
    [someArray] => Array
        (
            [0] => a third thing
            [1] => something
            [2] => somethingelse
        )

    [someArray2] => Array
        (
            [0] => something added
            [1] => somethingelse added
            [2] => a third thing added
        )

)

 

What I want to happen is test to see how SomeArray2->[1] compares to SomeArray->[1].  If it is less than, then leave it where it is.  If it is greater than, though, to move SomeArray2 above SomeArray in the results.  Does that make better sense?

Yup, you can reference variables of variables in pretty much all forms in php... even down to things that you should NEVER do because they're really really confusing

 

<?php
$one = 'two';
$a = 'one';
$b = 'a';
$c = 'b';

echo $$$$c; // outputs two
?>

 

you can do methods, functions, classes...

 

$class->$method();

$function();

new $class();

etc...

 

pretty much anything you can think of... unfortunately as you saw above it gets confusing so you should avoid doing it, or at least add a comment if you're forced to.

 

To be honest, I didn't have to use usort(), I could have, (and should have,) just used natcasesort().

 

EDIT: let me read your additon, I'll get back to you in a sec.

Okay, so can you go over what you want the output to be?

 

do you want it to combine the arrays and sort it? or perhaps to sort one and order the second accordingly?

 

Assuming the following is returned:

 

Array
(
    [0] => a third thing
    [1] => something
    [2] => somethingelse
)
Test Object
(
    [someArray] => Array
        (
            [0] => something added
            [1] => somethingelse added
            [2] => a third thing added
        )

    [someArray2] => Array
        (
            [0] => a third thing
            [1] => something
            [2] => somethingelse
        )

)

 

I want it to evaluate the results of TestObject->someArray->[1] and TestObject->someArray2->[1] and, upon seeing that someArray2->[1] is "smaller" than someArray->[1] sort it like:

 

Array
(
    [0] => a third thing
    [1] => something
    [2] => somethingelse
)
Test Object
(
    [someArray2] => Array
        (
            [0] => a third thing
            [1] => something
            [2] => somethingelse
        )

    [someArray] => Array
        (
            [0] => something added
            [1] => somethingelse added
            [2] => a third thing added
        )
)

 

EDIT: Perhaps it would help if I elaborated.  someArray is going to hold the details of an article.  The results that I'm getting are from a sql search to create an RSS feed.  I want it to list by, for example, [1] assuming that [1] is either of created_on, published_on, and updated_on dates.  Pre-sorting is necessary as the framework spits out the results dependant on the order in the Page Object that is being returned.  This paste bin holds the actual results returned from such a search.

Ohhhh okay, let me whip something up for that :) sorry

 

<?php
class Test {
public $parentArray = array();
private $sortAttribute;
   
public function add($array, $value) {
	$this->parentArray[$array][] = $value;
}

public function sort($attribute) {
	$this->sortAttribute = $attribute;
	uasort($this->parentArray, array($this, 'cmpVals'));
	return $this->parentArray;
}
  	
private function cmpVals($val1, $val2) {
	return strcasecmp($val1[$this->sortAttribute], $val2[$this->sortAttribute]);
}
}

$test = new Test();

$test->add('someArray', 'something added');
$test->add('someArray', 'somethingelse added');
$test->add('someArray', 'a third thing added');

$test->add('someArray2', 'a third thing');
$test->add('someArray2', 'something');
$test->add('someArray2', 'somethingelse');

print_r($test->sort(1));
?>

 

change it to uasort() to preserve the keys.

 

EDIT: fixed indentation

That's great generic!  Thank you so much.  I would like to be able to make a function like that on my own, do you have any recommended reading?  I find the php.net manuals to be rather...  cryptic.  I shouldn't have any problems reverse engineering your example to fit my own purposes, though.  Again, thanks so much!

Hmm.. recommended reading... well it really comes with just coding a ton and running into problems, then digging through the manual for functions that can do all that and using it to fix your problem. Of course, posting on this forum helps me encounter problems I've never run into before.

 

Indeed, to get a good walk through of many useful functions and techniques I always recommend ...

http://www.hudzilla.org/php/

... which covers everything from hello world to process control.

 

As far as books on proper object oriented design/design patterns go, I learned all mine from java books, so I don't know of any to recommend, but there are hundreds of threads in these forums littered with reading suggestions if you're willing to hunt them down. Now it's 2 am and I need a good sleep! Glad you've gotten it working, feel free to post any more questions here.

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.