Reputation: 1044
I have a result set that is queried from a database.
$promotions = array(
array('goods_num' => 2, 'promotion_type' => 'General goods', 'date' => '2020-02-04',),
array('goods_num' => 1, 'promotion_type' => 'Discount', 'date' => '2020-02-04',),
array('goods_num' => 1, 'promotion_type' => 'Flash sale', 'date' => '2020-02-04',),
array('goods_num' => 10, 'promotion_type' => 'Discount', 'date' => '2020-02-05',),
array('goods_num' => 10, 'promotion_type' => 'General goods', 'date' => '2020-02-05',),
array('goods_num' => 9, 'promotion_type' => 'Flash sale', 'date' => '2020-02-05',),
array('goods_num' => 2, 'promotion_type' => 'Flash sale', 'date' => '2020-02-06',),
array('goods_num' => 1, 'promotion_type' => 'General goods', 'date' => '2020-02-06',),
array('goods_num' => 2, 'promotion_type' => 'General goods', 'date' => '2020-02-06',),
array('goods_num' => 1, 'promotion_type' => 'General goods', 'date' => '2020-02-07',),
array('goods_num' => 2, 'promotion_type' => 'Flash sale', 'date' => '2020-02-07',),
array('goods_num' => 3, 'promotion_type' => 'Discount', 'date' => '2020-02-07',),
);
And I want to show it as a chart. like this demo,I want to convert the above array into this format:
array(
0 => array(0 => 'date', 1 => '2020-02-04', 2 => '2020-02-05', 3 => '2020-02-06', 4 => '2020-02-07',),
1 => array(0 => 'General goods', 1 => 2, 2 => 10, 3 => 3, 4 => 1,),
2 => array(0 => 'Discount', 1 => 1, 2 => 10, 3 => 0, 4 => 3,),
3 => array(0 => 'Flash sale', 1 => 1, 2 => 9, 3 => 2, 4 => 2,),
);
The first line is the date of the x-axis,After that is the sum of the goods_num in the date of each promotion.
I tried using two foreach loops to handle it, but I couldn't get the result I wanted. thank you all
Upvotes: 1
Views: 307
Reputation: 1085
function group_by($key, $data) {
$result = array();
foreach($data as $val) {
if(array_key_exists($key, $val)){
$result[$val[$key]][] = $val;
}else{
$result[""][] = $val;
}
}
return $result;
}
function format_chart($promotions){
$group_by_date = group_by("date", $promotions);
$dates = array_keys($group_by_date);
$top = array_merge(array("date"), $dates);
$data = array();
foreach($promotions as $promotion){
if(isset($data[$promotion['promotion_type']][$promotion['date']])){
$data[$promotion['promotion_type']][$promotion['date']] += $promotion['goods_num'];
}
else{
$data[$promotion['promotion_type']][$promotion['date']] = $promotion['goods_num'];
}
}
$final[] = $top;
foreach($data as $key => $val){
$row[] = $key;
foreach($dates as $date){
$count = 0;
if(isset($val[$date])){
$count = $val[$date];
}
$row[] = $count;
}
$final[] = $row;
$row = array();
}
return $final;
}
$formatted_data = format_chart($promotions);
Upvotes: 0
Reputation: 461
Here it is an example with raw PHP. But, you don`t have same count($keys) in your arrays, so:
# Create variables
$results = [];
$date = ['Date'];
$goods = ['General goods'];
$sale = ['Flash sale'];
$discount = ['Discount'];
# Fetch data
foreach ($promotions as $promo) {
# Getting general goods values
if (array_search('General goods', $promo)) {
array_push($goods, $promo['goods_num']);
array_push($date, $promo['date']);
}
# Getting flash sale values
if (array_search('Flash sale', $promo)) {
array_push($sale, $promo['goods_num']);
array_push($date, $promo['date']);
}
# Getting discount values
if (array_search('Discount', $promo)) {
array_push($discount, $promo['goods_num']);
array_push($date, $promo['date']);
}
}
# Construct results
array_push($results, $date);
array_push($results, $goods);
array_push($results, $sale);
array_push($results, $discount);
# Clear ram
unset($date, $goods, $sale, $discount, $promo);
# Printing results
echo "<pre>";
print_r($results);
And the results:
Array
(
[0] => Array
(
[0] => Date
[1] => 2020-02-04
[2] => 2020-02-04
[3] => 2020-02-04
[4] => 2020-02-05
[5] => 2020-02-05
[6] => 2020-02-05
[7] => 2020-02-06
[8] => 2020-02-06
[9] => 2020-02-06
[10] => 2020-02-07
[11] => 2020-02-07
[12] => 2020-02-07
)
[1] => Array
(
[0] => General goods
[1] => 2
[2] => 10
[3] => 1
[4] => 2
[5] => 1
)
[2] => Array
(
[0] => Flash sale
[1] => 1
[2] => 9
[3] => 2
[4] => 2
)
[3] => Array
(
[0] => Discount
[1] => 1
[2] => 10
[3] => 3
)
)
Upvotes: 1
Reputation: 23958
You can use array_column to get the dates then loop the array to build the goods_num.
$promotions = array(
array('goods_num' => 2, 'promotion_type' => 'General goods', 'date' => '2020-02-04',),
array('goods_num' => 1, 'promotion_type' => 'Discount', 'date' => '2020-02-04',),
array('goods_num' => 1, 'promotion_type' => 'Flash sale', 'date' => '2020-02-04',),
array('goods_num' => 10, 'promotion_type' => 'Discount', 'date' => '2020-02-05',),
array('goods_num' => 10, 'promotion_type' => 'General goods', 'date' => '2020-02-05',),
array('goods_num' => 9, 'promotion_type' => 'Flash sale', 'date' => '2020-02-05',),
array('goods_num' => 2, 'promotion_type' => 'Flash sale', 'date' => '2020-02-06',),
array('goods_num' => 1, 'promotion_type' => 'General goods', 'date' => '2020-02-06',),
array('goods_num' => 2, 'promotion_type' => 'General goods', 'date' => '2020-02-06',),
array('goods_num' => 1, 'promotion_type' => 'General goods', 'date' => '2020-02-07',),
array('goods_num' => 2, 'promotion_type' => 'Flash sale', 'date' => '2020-02-07',),
array('goods_num' => 3, 'promotion_type' => 'Discount', 'date' => '2020-02-07',),
);
$dates = array_unique(array_column($promotions , "date"));
$new[] = array(array_merge(['date'], $dates));
// Now the array has all the dates done
foreach($promotions as $item){
// Make associative array and place values in the subarrays
if(!isset($new[$item['promotion_type']])){
$new[$item['promotion_type']][] = $item['promotion_type'];
}
$new[$item['promotion_type']][] =$item['goods_num'];
}
//Remove associative array
$new = array_values($new);
var_dump($new);
Upvotes: 2
Reputation: 1044
I solved it with laravel's collection:
$dataSets = array_unique( array_column($promotions, 'date'));
$promotionTypes = array_unique(array_column($promotions, 'promotion_type'));
$promotionTypeOrders = $promotions->groupBy('promotion_type')->map(function ($item) {
return $item->groupBy('date');
});
$promotionGroups = [];
foreach ($dateSets as $dateSet) {
foreach ($promotionTypes as $promotionType) {
$promotionGroups[$promotionType][$dateSet] = isset($promotionTypeOrders[$promotionType][$dateSet]) ? $promotionTypeOrders[$promotionType][$dateSet]->sum('goods_num') : 0;
}
}
$result = [];
foreach ($promotionGroups as $promotionName => $promotionGroup) {
$result[] = array_merge([$promotionName], array_values($promotionGroup));
}
array_unshift($dateSets, 'date');
return array_merge([array_values($dateSets)], $result);
Upvotes: 2