Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I've searched google and stackoverflow for an answer but didn't find it...

I need to sort an array based on how much the item was sold. Then I need to sort it so that the priority (anything above zero) is moved to the top. The issue I'm having is that when I do the second sort (step 3) it unsort the sort from step 2.

Step 1: I have an array:

array(
    array(
        'title' => 'A',
        'priority' => 0,
        'sold_count' => 44
    ),
    array(
        'title' => 'B',
        'priority' => 2,
        'sold_count' => 0
    ),
    array(
        'title' => 'C',
        'priority' => 1,
        'sold_count' => 3
    ),
    array(
        'title' => 'D',
        'priority' => 0,
        'sold_count' => 33
    ),
)

Step 2: I sort it based on sold_count and get:

array(
    array(
        'title' => 'A',
        'priority' => 0,
        'sold_count' => 44
    ),
    array(
        'title' => 'D',
        'priority' => 0,
        'sold_count' => 33
    ),
    array(
        'title' => 'C',
        'priority' => 1,
        'sold_count' => 3
    ),
    array(
        'title' => 'B',
        'priority' => 2,
        'sold_count' => 0
    ),
)

Step 3: Sort it by its priority (what I should get).

array(
    array(
        'title' => 'B',
        'priority' => 2,
        'sold_count' => 0
    ),
    array(
        'title' => 'C',
        'priority' => 1,
        'sold_count' => 3
    ),
    array(
        'title' => 'A',
        'priority' => 0,
        'sold_count' => 44
    ),
    array(
        'title' => 'D',
        'priority' => 0,
        'sold_count' => 33
    ),
)

Instead of getting what I want (step 3) I get an array with the priority sorted right however all other guides after have a random order. All guides that don't have a priority (priority === 0) should not be resorted.

I've tried a bunch of methods using asort, aasort, custom foreach and setting the key and this multisort (example below but taken from here and here, the example 3).

$sorterA =
$sorterB = array();

foreach($array as $k => $v) {
  $sorterA[$k] = $k;
  $sorterB[$k] = $v['priority'];
}

array_multisort($sorterA, SORT_NUMERIC, $sorterB, SORT_DESC, SORT_NUMERIC, $array);

Note: Both sorts sorta need to be done separately (because the first sort isn't always sorted by sold_count but rather by date or other things).

share|improve this question
 
Did you try my answer from the first question you linked to? Sort first by priority descending and then by sold_count descending. –  Jon May 30 '13 at 9:16
 
Not yet. Let me check it out –  iDev247 May 30 '13 at 9:21
 
Have a look. –  Jon May 30 '13 at 9:22
 
Whoa! Amazing. Let me adventure a bit with your solution. I gave sold_count as an example however when I sort by priority I no longer have sold_count available (see my first comment on zerkms's answer). What I do have available is the original sort/keys. –  iDev247 May 30 '13 at 9:29
 
Alright. I came up with this. It's a hack but it works! –  iDev247 May 30 '13 at 9:41
show 2 more comments

1 Answer

up vote 2 down vote accepted

You just need to sort by 2 columns:

usort($arr, function($a, $b) {
    if ($a['priority'] == $b['priority']) {
        return $a['sold_count'] < $b['sold_count'] ? 1 : -1;
    }

    return $a['priority'] < $b['priority'] ? 1 : -1;
});

so it would sort by priority if the priorities differ, otherwise it sorts by sold_count

share|improve this answer
 
Looks like a great solution. I however loosely need to sort both separately (see the last note of my question). The reason is that first sorting (sold_count) isn't always sorted by sold_count. It was mostly for example. Sometimes it's sorted with its own other layer of sorting (no worries I cache all this). –  iDev247 May 30 '13 at 9:26
 
"to sort both separately" -- so change the comparer function correspondingly. "Separate" sort makes no sense - it's still a single sort by multiple criterias –  zerkms May 30 '13 at 9:55
 
Sorry for the confusion. It's cause my data is pulled form a sort of API. The API sorts the data. I don't have access to sold_count but I do have access to the way its sorted. Originally say the API would return title(priority): A(0), B(0), D(1), C(0), E(0) then I sorted it by priority I would get: D(1), E(0), B(0), A(0), C(0) (random sorting after the priority) instead of D(1), A(0), B(0), C(0), E(0). A hack from the solution Jon described above works great. Now that I think of it I could also use your solution but replace sold_count by priority. I'll update in a couple with a test. –  iDev247 May 30 '13 at 20:44
 
Your solution works! View here. View without your solution (see how they ones after the priority do not retain their original sort) –  iDev247 May 31 '13 at 1:29
 
@iDev247: I would wonder if it didn't work :-) –  zerkms May 31 '13 at 1:31
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.