简体   繁体   中英

Display total number of sales grouped per month

I posted this question before, someone here helped me get close to the solution but I can't seem to make it work to display the data like I need it to.

I have this array $sales which has a structure like below:

array(627) (

[0] => array(4) (
    [id]=> (int) 1
    [name] => (string) Tesla
    [total]=> (string) 24
    [month] => (string) 4
  )

[1] => array(4) (
    [id]=> (int) 1
    [name] => (string) Tesla
    [total]=> (string) 18
    [month] => (string) 5


[2] => array(4) (
    [id]=> (int) 1
    [name] => (string) Tesla
    [total]=> (string) 18
    [month] => (string) 6

[3] => array(4) (
    [id]=> (int) 2
    [name] => (string) Audi
    [total]=> (string) 16
    [month] => (string) 4
  )

[4] => array(4) (
    [id]=> (int) 2
    [name] => (string) Audi
    [total]=> (string) 18
    [month] => (string) 5

What it does is it stores sales information for each type of car and for each month. Some of the months don't have sales so they are blank. What I want to do is to loop through each type of car and display sales like below in an html table:

Car      Jan. Feb. Mar. Apr. May. Jun. Jul, Aug. Sept. Oct. Nov. Dec
Tesla    0    0    0    24   18   18   0    0     0    0    0     0
Audi     0    0    0    16   18    0   0    0     0    0    0     0

The problem is, The array I have only displays the month numer and the total if there have been sales in that month. In Tesla's case for example there were sales only on month 4, 5, 6 and I am missing 9 more months.

The help I got was:

$result = [];
foreach($sales as $sale) {
    if(!isset($result[$sale['name']]))
       $result[$sale['name']] = [];

    if(!isset($result[$sale['name']][$sale['month']]))
       $result[$sale['name']][$sale['month']] = $sale['total'];
    else
       $result[$sale['name']][$sale['month']] += $sale['total'];
}

This is fine, but how do I map each month of the year with this array? How do I display 0 for months without sale?

I hope you can help me with this. Is a bit complicated for me.

Updated:

foreach($cars as $car){
        echo '<tr><td>'.$car .'</td>';
            for($i=1;$i<=12;$i++){
            if (isset($new[$i][$car])){
                echo '<td>'.$new[$i][$car] . '</td>';
            }else{
                echo '<td>'."0".'</td>';
            }   
        }      
       echo '</tr>';
}

尝试将长度为12的数组初始化为0。如果相应索引的月份具有值,则将其更改,否则显示其初始化值

Here is one method that will first build a new array with month as first key, then a new subarray with the car as key and the value as the sales.

I then grab all cars with array_column and sort out duplicates with array_unique.

I then loop the months (1->12) and output with date() the month.
Then I loop the cars and output the values (sales).

foreach($sales as $sale){
    $new[$sale["month"]][$sale["name"]] = $sale["total"];
}

$cars = array_unique(array_column($sales, "name", "id"));
$cars[] = "Sum"; // add a car named "Sum" for later use of displaying the sum
//Var_dump($cars);
echo "<table>\n<th>Car</th>";

for($i=1;$i<=12;$i++){
    echo "<th>" . date("M", strtotime("2017-$i-01")) . "</th>"; // create header
    foreach($cars as $car){ // loop through the cars and add zero values to months if there is no sales on each car.
        if(!isset($new[$i][$car])){
            $new[$i][$car] = 0; // add months with 0 values
        }
    }
    $new[$i]["Sum"] = array_sum($new[$i]); // sum the month sales and add it to car "Sum"
}
ksort($new); // sort it on keys (months);

//output each car in a table (including "Sum") using array_column and implode
foreach($cars as $key => $car){
    If($car != "Sum"){
        echo "\n<tr><td><a href='$key'>$car</a></td><td>" . implode("</td><td>", array_column($new, $car)). "</td></tr>";
    }Else{
        echo "\n<tr><td>$car</td><td>" . implode("</td><td>", array_column($new, $car)). "</td></tr>"; 
    }
}

echo "</table>";

For php test:
https://3v4l.org/tZNOK
To see what the actual output is:
https://jsfiddle.net/gfjdcj4r/

Edit, added array_sum.
Edit; added html table Edit; added id as anchor by using the third option of array_column.
This makes the key of $cars the id.
This is then outputed as the anchor.

iterate your $result array and for every "car", iterate from 1 to 12 and for every month check if it's exists in the "car" result inner array

$result = [];
foreach($sales as $sale) {
    if(!isset($result[$sale['name']]))
        $result[$sale['name']] = [];

    if(!isset($result[$sale['name']][$sale['month']]))
        $result[$sale['name']][$sale['month']] = $sale['total'];
    else
        $result[$sale['name']][$sale['month']] += $sale['total'];
}

$totalSales = array();
foreach ($result AS $car=>$monthSales) {
    print $car;
    for($i=1;$i<=12;$i++) {
        if(array_key_exists($i, $monthSales)) {
            print $monthSales[$i]; // put here the names
        }
        else {
            print "0";
        }

        if(array_key_exists($i, $totalSales)) {
            $totalSales[$i] = 0;
        }
        $totalSales[$i] += (isset($monthSales[$i])) ? $monthSales[$i] : 0;
    }
}

for($i=1;$i<=12;$i++) {
   if(array_key_exists($i, $totalSales)) {
       print $totalSales[$i]; // put here the names
   }
   else {
       print "0";
   }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM