Nishant Jani
Nishant Jani

Reputation: 1993

sort associative array codeigniter php

Here is what I want to do:

$newArray = array();

foreach($student as $s){
    $newArray[$s->id][$s->grade] = $s;
}

I want to sort the students by their grades (more of a group than a sort) but I just want the grades to be sorted not the id. I could have don't this:

$newArray[$s->id] = $s->grade 
asort($newArray)

but I need the remaining data in $s. Also, there is huge chunk of data associated with each student which I want to maintain.

How can I achieve such a sorting?

Upvotes: 0

Views: 6283

Answers (2)

Elias Van Ootegem
Elias Van Ootegem

Reputation: 76405

Edit:

Sine you're working in a framework, best declare your sort callback as a member function (inside the same class as where you'll be needing it, of course):

private function sortCB(array $a, array $b)
{//the array type hinting in arguments is optional
    $i = array_keys($a);//but highly recommended 
    $j = array_keys($b);
    if (end($i) === end($j))
    {
        return 0;
    }
    //replace '>' with '<' if you want to sort descending
    return (end($i) > end($j) ? 1 : -1);//this is ascending
}

Then, in the method where the actual sorting is needed:

uasort($theArray,array($this,'sortCB'));

For more examples, see the docs. I've added a full class example at the end of this (bulky) answer


I've tried this on writecodeonline, which isn't all too good at this kind of stuff, but this did work:

$foo = array_fill_keys(array('foo','bar','q','Bond'),array());
$i = '256';
foreach($foo as $k=>$v)
{
    $foo[$k][$i] = $k;
    $i = (string)((int)$i%2 === 0 ? ((int)$i/2)+1 : (int)$i*3);
}
function sortCB($a,$b)
{
    $i = array_keys($a);
    $j = array_keys($b);
    if (end($i) === end($j))
    {
        return 0;
    }
    return (end($i) > end($j) ? 1 : -1);
}
uasort($foo,'sortCB');
var_dump($foo);

But since you're using a framework, you might do well declaring that function as a member function private function sortCB(array $a,array $b), and use it like so:

uasort($foo,array($this, 'sortCB'));

There might be some more info on how best to use this callback function in a class context here


Full example + usage (tested and working):

class test
{
    public $foo = null;
    public function __construct()
    {
        $this->foo = array_fill_keys(array('foo','bar','q','Bond'),array());
        $i = '256';
        foreach($this->foo as $k=>$v)
        {
            $this->foo[$k][$i] = $k;
            $i = (string)((int)$i%2 === 0 ? ((int)$i/2)+1 : (int)$i*3);
        }
    }
    private function sortCB($a,$b)
    {
        $i = array_keys($a);
        $j = array_keys($b);
        if (end($i) === end($j))
        {
            return 0;
        }
        return (end($i) > end($j) ? 1 : -1);
    }
    public function sortFoo()
    {
        uasort($this->foo,array($this,'sortCB'));
        print_r($this->foo);
        return $this->foo;
    }
}
$bar = new test();
$arr = $bar->sortFoo();

Upvotes: 11

Leri
Leri

Reputation: 12535

You can do something like:

foreach($student as $s){
    $newArray[$s->id] = $s;
}

usort($newArray, function ($a, $b) { return $a->grade - $b->grade; });

Edit

For later versions that don't support anonymous functions you can define comparison function first:

function sortByGrade($a, $b)
{
    return $a->grade - $b->grade;
}

usort($newArray, 'sortByGrade');

But if you get this data from db it would be easier to order it in your sql query. If you use ORM you can use its associated method.

Upvotes: 4

Related Questions