Skip to content
Advertisement

Sort array by 2nd level array count

I have an array that looks like this:

Array(
[172.17.0.2] => Array
    (
        [okok] => 1
    )

[172.17.0.1] => Array
    (
        [wp] => 3
        [ojopj] => 1
        [opjopj] => 1
    )

)

I need to be able to count the 2nd level contents and then sort the top level arrays based on these totals.

So for example my resultant array would look something like this:

Array(
  [172.17.0.2] => 1
  [172.17.0.1] => 5
)

I then ideally want to sort by descending order and show only the top 5 results.

At present my code consists of the following:

foreach ($iplog as $ip => $arr) {
    foreach ($arr as $user => $count) {
        $count_desc = $count_desc + $count;
    }
    $output .= $count_desc;
    $output .= '</span><hr style="width:100%">';
}

However, this doesn’t take care of any sorting or limiting the results to the top 5. Based on the code I have so far, I can only envisage create more for loops to build a new array, sort it and so on.

Is there a much more efficient way to achieve the results I need?

Advertisement

Answer

Easy enough in a few lines:

$x = array_map('array_sum', $iplog); // sum the values
arsort($x, SORT_NUMERIC); // reverse sort
$y = array_slice($x, 0, 5, true); // top 5

Importantly, each of these transformations preserves the keys. In PHP, there are array functions that do, and functions that do not, preserve keys. Being aware of this saves some grief.

Side note, if an IP has an empty array, that’s treated as zero.

User contributions licensed under: CC BY-SA
2 People found this is helpful
Advertisement