CodeIgniter Forums

Full Version: Sorting an Array with Objects
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Pages: 1 2

El Forum

[eluser]elaniobro[/eluser]
Trying to sort an array I have with the following results:
Code:
Array
(
    [0] => stdClass Object
        (
            [id] => 10
            [date] => May 2005 – August 2005
            [location] => Bethesda, MD
            [company] => Company 1
            [job_title] => Web Design Assistant
            [description] => <ul class="resume-list">

    <li>Lorem Ipsum Dolor</li>
    <li>Lorem Ipsum Dolor</li>
    <li>Lorem Ipsum Dolor</li>
</ul>
        )

    [1] => stdClass Object
        (
            [id] => 20
            [date] => January – May 2006
            [location] => Bethesda, MD
            [company] => Company 2
            [job_title] => Web Designer/Developer
            [description] => <ul class="resume-list">
    <li>Lorem Ipsum Dolor</li>
    <li>Lorem Ipsum Dolor</li>
    <li>Lorem Ipsum Dolor</li>
</ul>
        )

    [2] => stdClass Object
        (
            [id] => 2
            [date] => August 2006
            [location] => New York, NY
            [company] =>  Company 3
            [job_title] => Web Developer
            [description] => <ul class="resume-list">
    <li>Lorem Ipsum Dolor</li>
    <li>Lorem Ipsum Dolor</li>
    <li>Lorem Ipsum Dolor</li>
</ul>

        )

    [3] => stdClass Object
        (
            [id] => 1
            [date] => November 2006 – November 2007
            [location] => Chantilly, VA
            [company] =>  Company 4
            [job_title] => Interactive Designer/Developer
            [description] => <ul class="resume-list">
    <li>Lorem Ipsum Dolor</li>
    <li>Lorem Ipsum Dolor</li>
    <li>Lorem Ipsum Dolor</li>
</ul>
        )

)

I would like to sort this array by the [id].

I have tried to do the following but have failed:
Code:
&lt;?php
        
        
            #print_r ($query->result());
            $input = $query->result();
            #$result= array_reverse($input);

            function compare_id($a, $b)
            {
                return strnatcmp($a->id, $b->id);
            }
            
            uasort($query, 'compare_id');
            print_r (uasort($query, 'compare_id'));
            foreach($result as $row):?&gt;
            <div class="trigger">          
            <p class="resume_date">&lt;?=$row->date?&gt;</p>  
            <h2 class="resume_company"><a href="#">&lt;?=$row->company?&gt;</a> </h2>
            </div>
            <div class="toggle_container">
                <div class="block">
                        <h1 class="resume-title">&lt;?=$row->job_title?&gt;</h1>
                    &lt;!--Content--&gt;
                        <p class="resume-location">&lt;?=$row->location?&gt;</p>
                        <div class="clear"></div>
                        <p class="resume-content">&lt;?=$row->description?&gt;</p>
                        <br />
                </div>
            </div>
                         <div class="clear"></div>

        &lt;?php endforeach;?&gt;

any ideas?

El Forum

[eluser]Kamarg[/eluser]
Pass the array of objects as the first parameter and the object member to sort on as the second parameter.
Code:
function _osort(&$array, $p) {
    usort($array, create_function('$a,$b', 'if($a->' . $p . ' == $b->' . $p . ') { return 0; } else { return ($a->' . $p . ' > $b->' . $p . ' ? 1 : -1); }'));
}

El Forum

[eluser]elaniobro[/eluser]
Thanks Kamrag,

I will give it a whirl. Seeing as I am new to php and more so to codeigniter, would you mind re-writing the code in long hand? I am not used to the '?' in the else statement and it is hard for me to read. Or better yet, could you comment for me what is going on so I may dissect, interpret, learn and understand!

Thanks again, and cheers! I'll let you know how it works for me.

El Forum

[eluser]danmontgomery[/eluser]
Code:
return ( $value == 'some value' ? true : false );

is identical to

Code:
if($value == 'some value') {
    return true;
} else {
    return false;
}

(and this is just me being picky, but the ternary operator is not specific to PHP)

El Forum

[eluser]elaniobro[/eluser]
Perhaps my code has syntax errors, or I am just passing the wrong parameters, but it's not working:

Code:
&lt;?php
        
            #print_r ($query->result());
            $input = $query->result();
            $result= array_reverse($input);


            function _osort($input, $p) {
                usort($input, create_function('$a,$b', 'if($a->' . $p . ' == $b->' . $p . ') { return 0; } else { return ($a->' . $p . ' > $b->' . $p . ' ? 1 : -1); }'));
            }


            foreach($result as $row):?&gt;
            <div class="trigger">          
            <p class="resume_date">&lt;?=$row->date?&gt;</p>  
            <h2 class="resume_company"><a href="#">&lt;?=$row->company?&gt;</a> </h2>
            </div>
            <div class="toggle_container">
                <div class="block">
                        <h1 class="resume-title">&lt;?=$row->job_title?&gt;</h1>
                    &lt;!--Content--&gt;
                        <p class="resume-location">&lt;?=$row->location?&gt;</p>
                        <div class="clear"></div>
                        <p class="resume-content">&lt;?=$row->description?&gt;</p>
                        <br />
                </div>
            </div>
                         <div class="clear"></div>

        &lt;?php endforeach;?&gt;

Not quite sure what '$p' is, maybe shedding light on that will help.

El Forum

[eluser]Kamarg[/eluser]
You just about had it. Put a & in front of $input in your function declaration so that _osort can modify the contents of $input. Then you just need to call _osort somewhere passing $input as the first parameter and 'id' or whatever object member you want to sort on.

As far as the overall code goes, the _osort function takes an array by reference (so that changes persist when the function returns) which is indicated by the & and a string of the index to sort the array on. It then calls usort passing the array to sort as the first parameter. For the second parameter it creates an anonymous function with two parameters ($a and $b) with the function body being the text. The anonymous function body is just a simple test to see if the value of a specific object member is equal, in which case it returns zero or returns 1 or -1 depending on if $a or $b is larger.

I'm not very good at explaining but I hope that helps.

El Forum

[eluser]elaniobro[/eluser]
[quote author="Kamarg" date="1268099150"]You just about had it. Put a & in front of $input in your function declaration so that _osort can modify the contents of $input. Then you just need to call _osort somewhere passing $input as the first parameter and 'id' or whatever object member you want to sort on.

As far as the overall code goes, the _osort function takes an array by reference (so that changes persist when the function returns) which is indicated by the & and a string of the index to sort the array on. It then calls usort passing the array to sort as the first parameter. For the second parameter it creates an anonymous function with two parameters ($a and $b) with the function body being the text. The anonymous function body is just a simple test to see if the value of a specific object member is equal, in which case it returns zero or returns 1 or -1 depending on if $a or $b is larger.

I'm not very good at explaining but I hope that helps.[/quote]

This does make sense, more so then just looking at the code, thanks for the explanation. As for the implemenatatin I put the following in my view file, while no errors are happening, the sorting by the 'id' is not happening.

Code:
&lt;?php
        
            #print_r ($query->result());
            $input = $query->result();
            $result= array_reverse($input);


            function _osort(&$input, $p) {
                usort($input, create_function('$a,$b', 'if($a->' . $p . ' == $b->' . $p . ') { return 0; } else { return ($a->' . $p . ' > $b->' . $p . ' ? 1 : -1); }'));
            }

            _osort($input, 'id');
            foreach($result as $row):?&gt;
            <div class="trigger">          
            <p class="resume_date">&lt;?=$row->date?&gt;</p>  
            <h2 class="resume_company"><a href="#">&lt;?=$row->company?&gt;</a> </h2>
            </div>
            <div class="toggle_container">
                <div class="block">
                        <h1 class="resume-title">&lt;?=$row->job_title?&gt;</h1>
                    &lt;!--Content--&gt;
                        <p class="resume-location">&lt;?=$row->location?&gt;</p>
                        <div class="clear"></div>
                        <p class="resume-content">&lt;?=$row->description?&gt;</p>
                        <br />
                </div>
            </div>
                         <div class="clear"></div>

        &lt;?php endforeach;?&gt;

Perhaps I need to add or put the function call else where?

El Forum

[eluser]elaniobro[/eluser]
Well, I tried print_r(_osort($input, 'id')); and nothing is printing.

Ideas?

El Forum

[eluser]danmontgomery[/eluser]
If this array is just a sql result, why not just sort the query by id?

El Forum

[eluser]Kamarg[/eluser]
noctrum: That does seem to be a rather better idea. Sometimes it pays to look at the whole block of code instead of just the short bit your interested in I suppose. Smile

elaniobro: Nothing is printing because _osort doesn't return a value so the print_r call isn't being passed a parameter. You need to make that into two lines.
Code:
_osort($input, 'id');
print '<pre>' . print_r($input, true) . '</pre>';
Pages: 1 2