1

I have a function sortBy() that I use to sort multidimensional arrays by a particular key. Here is a sample array:

Array
(
[0] => Array
    (
        [id] => 4
        [type] => 1
        [game] => 1
        [platform] => 0
        [TotalPot] => 7550
    )

[1] => Array
    (
        [id] => 5
        [type] => 0
        [game] => 2
        [platform] => 0
        [TotalPot] => 7500
    )

)

Here is the function

function sortBy($arr, $field='id', $order=1) {
    $a = array();
    if ( !is_array($arr) )
        return false;
    foreach($arr as $subArr) {
        $a[$subArr[$field]] = $subArr;
    }

    if ( $order == 1 ) sort($a);
    else rsort($a);

    return $a;
}

In this case, calling sortBy($array, 'TotalPot'); would work fine, because the two values for TotalPot are different. However, if you run this example and set both TotalPot fields to $7500, it overwrites the first occurrence with the latter.

What would be the best way to make this function allow for two items with the same value but still keep them in relevant order? I thought about adding another character, an A or 1 to the end, but this seems sloppy and not very predictable, so a better course of action would be greatly appreciated.

SISYN
  • 2,209
  • 5
  • 24
  • 45

2 Answers2

2

The reason they are getting overwritten is because you're creating an array where the index is the value of the totalPot.

If there are duplicates, then you will only have one array element with the totalPot.

Easiest way is just to usort this:

<?php

$array = [
    [
        "id" => 4,
        "type" => 1,
        "game" => 1,
        "platform" => 0,
        "TotalPot" => 7550
    ], [
        "id" => 5,
        "type" => 0,
        "game" => 2,
        "platform" => 0,
        "TotalPot" => 7500
    ]
];

usort($array, function($a, $b) {
    return $a['TotalPot'] - $b['TotalPot'];
});

print_r($array);

Output:

Array
(
    [0] => Array
        (
            [id] => 5
            [type] => 0
            [game] => 2
            [platform] => 0
            [TotalPot] => 7500
        )

    [1] => Array
        (
            [id] => 4
            [type] => 1
            [game] => 1
            [platform] => 0
            [TotalPot] => 7550
        )

)

You can also make this a function:

function sortBy($arr, $field='id', $order=1) {
    usort($arr, function($a, $b) use ($field, $order) {
        if ($order == 1)
            return $a[$field] - $b[$field];
        else
            return $b[$field] - $a[$field];
    });
}
Dave Chen
  • 10,887
  • 8
  • 39
  • 67
2

You can simplify your code and just use usort(), e.g.

function sortArrayByField(array &$arr, $field = "id", $ASC = TRUE) {
    usort($arr, function($a, $b)use($field, $ASC){
        if($a[$field] == $b[$field])
            return 0;
        return $a[$field] > $b[$field] ? $ASC : !$ASC;
    });
}

Then just call it like this:

sortArrayByField($array, "TotalPot", TRUE);
print_r($array);
Rizier123
  • 58,877
  • 16
  • 101
  • 156