1

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.

Joshua Berry
  • 2,230
  • 3
  • 21
  • 24

2 Answers2

2
<?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.

rrehbein
  • 4,120
  • 1
  • 17
  • 23
  • How can i get the total count for each of them? I need to display how many times each of them existed as well. – Gary Senter Nov 05 '12 at 14:21
  • In php, you could create a tally hash in the loop that totals the quantities "$tally[$cause]++;" or if it is an option, in the SQL add 'COUNT(qty) as tally' to the select clause. – rrehbein Nov 06 '12 at 18:15
  • Is this right?`foreach ($qp_cause_array as $entry) { if (!isset($qptotals[$entry['cause']])) { $qptotals[$entry['cause']] = 0; } $qptotals[$entry['cause']] += $entry['qty']; $tally[$cause]++; }` – Gary Senter Nov 07 '12 at 16:48
  • Fairly close. $cause isn't defined inside the foreach loop. Edited my answer to include this additional feature. – rrehbein Nov 07 '12 at 16:54
1

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.

NappingRabbit
  • 1,888
  • 1
  • 13
  • 18