Gary Senter
Gary Senter

Reputation: 29

Array of objects top 5 unique values

I have an array of arrays with two specific key/value pairs. What I am trying to do is to get the top 5 unique cause values decided by qty. Meaning that it would group the cause keys together by unique values, then total up the qty keys for each cause, and return the top 5 causes and the total qty for each cause.

Here is what the print_r(array_values($array)) prints out.

Array ( 
[0] => Array ( [cause] => Other (please comment) [qty] => 0.417 ) 
[1] => Array ( [cause] => Chem Out FC-DryStrAddTow [qty] => 0.430 ) 
[2] => Array ( [cause] => Chem Out FC-DryStrAddTow [qty] => 0.430 ) 
[3] => Array ( [cause] => Chem Out FC-DryStrAddTow [qty] => 0.513 ) 
[4] => Array ( [cause] => Chem Out FC-DryStrAddTow [qty] => 0.513 ) 
[5] => Array ( [cause] => Chem Out FC-DryStrAddTow [qty] => 0.750 ) 
[6] => Array ( [cause] => Chem Out FC-DryStrAddTow [qty] => 0.750 ) 
[7] => Array ( [cause] => Slitter Cut/Saw-Poor Cut [qty] => 0.816 ) 
[8] => Array ( [cause] => Slitter Cut/Saw-Poor Cut [qty] => 0.816 ) 
[9] => Array ( [cause] => Slitter Cut/Saw-Poor Cut [qty] => 0.828 ) 
[10] => Array ( [cause] => Slitter Cut/Saw-Poor Cut [qty] => 0.828 ) 
[11] => Array ( [cause] => Slitter Cut/Saw-Poor Cut [qty] => 0.681 ) 
[12] => Array ( [cause] => Slitter Cut/Saw-Poor Cut [qty] => 0.681 ) 
[13] => Array ( [cause] => No Cause Selected [qty] => 0.918 ) 
[14] => Array ( [cause] => No Cause Selected [qty] => 0.918 ) 
[15] => Array ( [cause] => No Cause Selected [qty] => 0.926 ) 
[16] => Array ( [cause] => No Cause Selected [qty] => 0.937 ) 
[17] => Array ( [cause] => No Cause Selected [qty] => 0.809 ) 
[18] => Array ( [cause] => No Cause Selected [qty] => 0.809 ) 
[19] => Array ( [cause] => Slitter Cut/Saw-Poor Cut [qty] => 0.891 ) 
[20] => Array ( [cause] => Slitter Cut/Saw-Poor Cut [qty] => 0.891 ) 
[21] => Array ( [cause] => Slitter Cut/Saw-Poor Cut [qty] => 0.884 ) 
[22] => Array ( [cause] => Slitter Cut/Saw-Poor Cut [qty] => 0.884 ) ) 

Thank you in advance for your help.

Upvotes: 1

Views: 211

Answers (2)

rrehbein
rrehbein

Reputation: 4170

<?php

// Total up the quantities
$totals = array();
$tally  = array();
foreach ($datapoints as $entry) {
    if (!isset($totals[$entry['cause']]) {
        $totals[$entry['cause']] = 0;
        $tally[$entry['cause']]  = 0;
    }
    $totals[$entry['cause']] += $entry['qty'];
    $tally[$entry['cause']]++;
}

// Sort them, 'descending' or 'reverse', so the larger entries are first
arsort($totals, SORT_NUMERIC);

// Take the first 5 entries from the sorted list
$top = array_slice($totals, 0, 5);

// Do something with it.
foreach ($top as $cause => $totalQty) {
    echo $cause . ': ' . $totalQty . ' with ' . $tally[$cause] . ' events' . PHP_EOL;
}

If this data is coming from a database though, it would be better to use the database and SQL, with something like:

SELECT cause, SUM(qty) as totalQty, COUNT(qty) as tally
FROM data
GROUP BY cause
ORDER BY totalQty DESC
LIMIT 5;

Rather then load all the data and processing in php.

Upvotes: 2

NappingRabbit
NappingRabbit

Reputation: 1918

if using php 5.3+ you can use closures in your code and sort like (descending by qty)

usort($arary,function($a,$b){
    return $b['qty'] - $a['qty']
}

after this you can loop through the array and take the first 5 uniques.

Upvotes: 1

Related Questions