1

I have something like this:

$i = 0;

foreach($tracks['results'] as $track){
    $trackName[$i] = $track['name'];
    $trackPlaycount[$track['name']] = $track['playcount'];
    $trackPercent[$track['name']] = $track['percent'];
    $i++;
}

$this->trackName = $trackName;
$this->trackPlaycount = $trackPlaycount;
$this->trackPercent = $trackPercent;

how could I sort these objects by playcount? From what I have read so far I understand I should probably create a compare function and then make it work with usort(), right? But I'm not quite sure how to accomplish that...

thank you




edit: ok, so now I've got it like this:

public function firstmethod(){
    // there are some more parameters here of course
    // but they worked before, not important for the problem
    $i = 0;
    foreach($tracks['results'] as $track){
        $trackName[$i] = $track['name'];
        $trackPlaycount[$track['name']] = $track['playcount'];
        $trackPercent[$track['name']] = $track['percent'];
        // this part is new
        $tracksArray[$i] = array(
            'name' => $trackName[$i], 
            'playcount' => $trackPlaycount[$track['name']], 
            'percentage' => $trackPercent[$track['name']]
        );
        $i++;
    }

    usort($tracksArray, array($this, 'sortByCount'));

    $i = 0;
    // this is to put the new sorted array into the old variables? 
    foreach($tracksArray as $temp){
        $trackName[$i] = $temp['name'];
        $trackPlaycount[$trackName[$i]] = $temp['playcount'];
        $trackPercent[$trackName[$i]] = $temp['percentage'];
        $i++;
    }

    $this->trackName = $trackName;
    $this->trackPlaycount = $trackPlaycount;
    $this->trackPercent = $trackPercent;
}


public function sortByCount($a, $b){
    if($a["playcount"] == $b["playcount"]) {
        return 0;
    }
    return ($a["playcount"] < $b["playcount"]) ? -1 : 1;
}   

this now works... thank you everyone

1
  • Edited my answer so it includes sorting by integer fields if that was giving you the trouble, hope it helps Commented Aug 18, 2010 at 12:27

2 Answers 2

7

usort example:

In the custom function you just access the array key you care about like this:

?php
$people = array(
    array('id' => 1, 'name' => 'John', 'age' => 12),
    array('id' => 2, 'name' => 'Mary', 'age' => 14),
    array('id' => 3, 'name' => 'Aaaaaadam', 'age' => 15)
);

usort($people, "sortByName");
var_dump($people);
usort($people, "sortByAge");
var_dump($people);

function sortByName($a, $b) {
    return strcmp($a["name"], $b["name"]);
}

function sortByAge($a, $b) { // or playcount or whatever
    if($a["age"] == $b["age"]) {
        return 0;
    }
    return ($a["age"] < $b["age"]) ? -1 : 1;
}

prints the sorted array (only pasted one so it's not getting to long, other output accordingly sorted by age)

array(3) {
  [0]=>
  array(3) {
    ["id"]=>
    int(3)
    ["name"]=>
    string(9) "Aaaaaadam"
    ["age"]=>
    int(15)
  }
  [1]=>
  array(3) {
    ["id"]=>
    int(1)
    ["name"]=>
    string(4) "John"
    ["age"]=>
    int(12)
  }
  [2]=>
  array(3) {
    ["id"]=>
    int(2)
    ["name"]=>
    string(4) "Mary"
    ["age"]=>
    int(14)
  }
}
Sign up to request clarification or add additional context in comments.

3 Comments

so, I should first populate this array of arrays, in my loop and then sort it with a function? and one more thing.. since this should all be done inside a class, could I make this sort function a private method and then use it like usort($people, $this->sortByAge); or that kind of approach won't work?
that kind of approach will work, except passing instance methods as callbacks is done like array($this, "sortByAge"), or for static methods like array("ClassName", "sortByAge").
Thanks for the callback with classes example @gnud , +1
5

You could also use an SplMaxHeap for this. Borrowing @edorian's $people array, you can do

class SortByAge extends SplMaxHeap
{
    function compare($a, $b)
    {
        return $a['age'] - $b['age'];
    }
}

$sort = new SortByAge;
foreach($people as $person) {
    $sort->insert($person);
}

print_r(iterator_to_array($sort));

This should perform somewhat better than usort.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.