Hello I've got two arrays, one which is made with Carbon that takes the last 12 months from today (in Y-m format) and a Collection (which have an array of items that return every transaction of the last 12 months in the same Y-m format). What I want to do is fill in this items array if there's no transaction for example on the month 12, 9, 8 fill them with 0.
Here's the 2 arrays I need compared and fill missing Year-month with 0 (the last array is the balance which will be merged into the array for every month).
^ array:12 [▼
"2022-02" => 0
"2022-03" => 0
"2022-04" => 0
"2022-05" => 0
"2022-06" => 0
"2022-07" => 0
"2022-08" => 0
"2022-09" => 0
"2022-10" => 0
"2022-11" => 0
"2022-12" => 0
"2023-01" => 0
]
^ array:12 [▼
"2022-01" => 0
"2022-02" => 1
"2022-03" => 2
"2022-04" => 3
"2022-06" => 4
"2022-07" => 5
"2022-08" => 6
"2022-09" => 7
"2022-10" => 8
"2022-11" => 9
"2022-12" => 10
"2023-01" => 11
]
^ array:12 [▼
0 => 340
1 => 480
2 => 550
3 => 690
4 => 830
5 => 970
6 => 1110
7 => 1250
8 => 1460
9 => 1600
10 => 1670
11 => 1880
]
The code I used at the moment to find the balance per month (the latest balance of the month) but at the moment I dont print the missing months (it just skips them instead of filling with 0):
$period = CarbonPeriod::create(now()->subMonths(11), now())->month();
$dates = array();
$days = array();
foreach($period as $date) {
$dates[] = $date->format("Y-m");
$days[] = $date->lastOfMonth()->format("d-m-Y");
}
$userTransactions = auth()->user()->transactions;
$flipped = array_flip($dates);
$transactionsByMonth = $userTransactions->groupBy(function($d) {
$monthlyTransaction = Carbon::parse($d->created_at)->format('Y-m');
return $monthlyTransaction;
});
foreach($flipped as $key => $yearMonth){
$yearMonth = 0;
$flipped[$key] = $yearMonth;
}
dump($flipped);
foreach($transactionsByMonth as $transaction) {
if (sizeof($transaction) > 1){
$duplicatedTransactions = $transaction->groupBy(function($d) {
return Carbon::parse($d->created_at)->format('Y-m-d');
});
$lastDuplicatedTransactions = $duplicatedTransactions->last();
foreach($lastDuplicatedTransactions as $lastTransaction){
$transactionDates[] = $lastTransaction->created_at;
$transactionBalance[] = $lastTransaction->main_balance;
}
} else {
foreach($transaction as $notDuplicatedTransaction){
$transactionDates[] = $notDuplicatedTransaction->created_at;
$transactionBalance[] = $notDuplicatedTransaction->main_balance;
}
}
};
$transactionsPerMonth = [];
foreach($transactionDates as $date){
$date = Carbon::parse($date)->format('Y-m');
$transactionsPerMonth[] = $date;
}
$transactionsPerMonth = array_flip($transactionsPerMonth);
dump($transactionsPerMonth);
dump($transactionBalance);
At the moment I achieved printing the balance of the oldest day of the month on the last 12 months, what Im missing is comparing if of this 12 months if there's a month missing fill it with 0 instead of skipping it.
Improved the code to this:
$months = CarbonPeriod::create(now()->subMonths(11), now())->month();
$transactions = auth()->user()->transactions
->groupBy( fn($d) => Carbon::parse( $d->created_at )->format('Y-m'))->map->last();
$transactionsByMonth = collect($months)
->flatMap(function ($key) use ($transactions) {
$key = $key->format('Y-m');
return [$key => collect($transactions[$key]->main_balance ?? 0)];
});
$transactionsByMonth = $transactionsByMonth->toArray();
$transactionsByMonth = array_values($transactionsByMonth);
dump($transactionsByMonth);
But Im getting an array inside an array:
array:12 [▼
0 => array:1 [▼
0 => 480
]
1 => array:1 [▼
0 => 550
]
2 => array:1 [▼
0 => 690
]
3 => array:1 [▶]
4 => array:1 [▶]
5 => array:1 [▶]
6 => array:1 [▶]
7 => array:1 [▶]
8 => array:1 [▶]
9 => array:1 [▶]
10 => array:1 [▶]
11 => array:1 [▶]
]
So What I finally did to solve it was instead of returning the collect() for every $key I just returned the collect directly so I would stop getting an array inside an array.
Replaced this:
$transactionsByMonth = collect($months)
->flatMap(function ($key) use ($transactions) {
$key = $key->format('Y-m');
return [$key => collect($transactions[$key]->main_balance ?? 0)];
});
$transactionsByMonth = $transactionsByMonth->toArray();
$transactionsByMonth = array_values($transactionsByMonth);
dump($transactionsByMonth);
Into this:
$transactionsByMonth = collect($months)
->flatMap(function ($key) use ($transactions) {
$key = $key->format('Y-m');
return collect($transactions[$key]->main_balance ?? 0);
});
$transactionsByMonth = $transactionsByMonth->toArray();