How can I remove duplicate array in between two arrays - php

I want to remove same array between 2 array
1 ) $getAlldate
array:8 [▼
0 => "2018-08-17"
1 => "2018-08-20"
2 => "2018-08-21"
3 => "2018-08-22"
4 => "2018-08-23"
5 => "2018-08-24"
6 => "2018-08-27"
7 => "2018-08-28"
]
2) $getHoliday
array:7 [▼
0 => "2019-1-1"
1 => "2019-3-6"
2 => "2019-2-28"
3 => "2019-5-2"
4 => "2019-4-25"
5 => "2018-8-27"
6 => "2018-8-28"
]
As you see in my array 2018-08-27,2018-08-28 are duplicate with $getholiday I try to use array_diff and It still didnt work
$a = array_diff($getAllDate, $getHoliday);
$b = array_unique($a);
How can I output like this $getalldate remove same value $getHoliday
array:8 [▼
0 => "2018-08-17"
1 => "2018-08-20"
2 => "2018-08-21"
3 => "2018-08-22"
4 => "2018-08-23"
5 => "2018-08-24"
]

The format of both the dates are diffrent.
Try:
PHP Code:
$getAlldate = [
"2018-08-17",
"2018-08-20",
"2018-08-21",
"2018-08-22",
"2018-08-23",
"2018-08-24",
"2018-08-27",
"2018-08-28"
];
$getHoliday=[
"2019-1-1",
"2019-3-6",
"2019-2-28",
"2019-5-2",
"2019-4-25",
"2018-8-27",
"2018-8-28"
];
$formattedHoliday = array_map(function ($holiday) {
$alldateFormat = 'Y-m-d';
$HolidayFormat = 'Y-n-d';
$date = DateTime::createFromFormat($HolidayFormat, $holiday);
return $date->format($alldateFormat);
}, $getHoliday);
var_dump(array_diff($getAlldate, $formattedHoliday));
Output: https://3v4l.org/rCLCk
Refer:
DateTime::createFromFormat: http://php.net/manual/en/datetime.createfromformat.php
DateTime::format: http://php.net/manual/en/datetime.format.php

Related

Compare two arrays and if one month (key) is missing fill with 0

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.
You can use array_key_exists() function to compare the two arrays and fill in missing months with 0.
Example:
$carbonMonths = ["2022-01", "2022-02", "2022-03", "2022-04", "2022-05", "2022-06", "2022-07", "2022-08", "2022-09", "2022-10", "2022-11", "2022-12"];
$transactions = [
["2022-01" => 200],
["2022-02" => 150],
["2022-03" => 100],
["2022-05" => 50]
];
foreach ($carbonMonths as $month) {
if (!array_key_exists($month, $transactions)) {
$transactions[$month] = 0;
}
}
In this example, the $carbonMonths array contains the last 12 months in Y-m format. The $transactions array contains transactions in the same format.
You can also use the array_merge() function to merge the two arrays and fill in any missing values with 0.
$merged = array_merge(array_fill_keys($carbonMonths, 0), $transactions);
Here $transactions should be an associative array with keys as month and value for this to work.
Both of the approach should give you the same result, you may use the one which you find easy to implement.
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();

How to get values from an array in Laravel

I have a 3 level category. I need to gain businesses on level 3 category.
I write this code:
$main_cat = Category::where(['slug' => $url])->first();
$lev_cat2 = Category::where(['parent_id' => $main_cat->id, 'status' => '1'])->get();
foreach ($lev_cat2 as $subCategory) {
$cat_ids_lv2[] = $subCategory->id . ',';
}
foreach ($lev_cat2 as $subCat) {
$lev_cat3[] = Category::where(['parent_id' => $subCat->id, 'status' => '1'])->pluck('id')->toArray();
}
dd($lev_cat3);
Then I got this array which is correct:
array:5 [▼
0 => array:3 [▼
0 => 145
1 => 146
2 => 147
]
1 => array:3 [▼
0 => 148
1 => 149
2 => 150
]
2 => array:3 [▼
0 => 151
1 => 152
2 => 153
]
3 => array:3 [▼
0 => 154
1 => 155
2 => 156
]
4 => []
]
now I dont know how can I get values like 145,146,147,148,149,... to pass theme to
Business::where(['category_id'=> [145,146,147,148,...]]->get();
of course dynamic.
You can use laravel collection helpers :
Business::whereIn('category_id', collect($lev_cat3)->flatten()->all())->get();
Since PHP 5.5.0 there is a built-in function array_column which does exactly this.
You can use it to Converting php array of arrays into single array then use it like this
$category_ids = array_column($lev_cat3);
Business::where(['category_id'=> $category_ids]]->get();

PHP- Sorting multidimensional array into another by range of numbers

I have a multidimensional array that I get from DB. Array has a number of views by each hour that is logged in the DB as a view, and it looks like this:
array:11 [▼
0 => array:2 [▼
"hour" => 0
"views" => 1
]
1 => array:2 [▼
"hour" => 1
"views" => 1
]
2 => array:2 [▼
"hour" => 4
"views" => 1
]
...and so on
]
I need to make a new array that will contain number of views for range of 2 hours. So for example from the array shown above I would like to get an array with, number of views for time between 0-2, that would 2, and for 2-4, would be 0 in this case, and so on.
You can do it in Mysql query:
select floor(hour/2) range, sum(views) sum
from thetable
group by range
You can just use a foreach to create a new array.
<?php
$your_array = [0 => [
"hour" => 0,
"views" => 4
],
1 => [
"hour" => 1,
"views" => 12
],
2 => [
"hour" => 4,
"views" => 1
],
3 => [
"hour" => 2,
"views" => 9
],
4 => [
"hour" => 21,
"views" => 19
]
];
foreach ($your_array as $value){
for($i=0;$i<=22;$i=$i+2){
$j=$i+2;
if($value['hour']>=$i && $value['hour']<$j){
isset($result[$i.'-'.$j])?$result[$i.'-'.$j]+=$value['views']:$result[$i.'-'.$j]=$value['views'];
}
}
}
print_r($result);
Try below code.
$arr = [0 => [
"hour" => 0,
"views" => 1
],
1 => [
"hour" => 1,
"views" => 1
],
2 => [
"hour" => 4,
"views" => 1
]];
foreach($arr as $row)
{
if($row['hour'] >= 0 && $row['hour'] <= 2)
{
$newArr['0-2'] = isset($newArr['0-2']) ? ($newArr['0-2'] + 1) : 1;
}
if($row['hour'] > 2 && $row['hour'] < 4)
{
$newArr['2-4'] = isset($newArr['2-4']) ? ($newArr['2-4'] + 1) : 1;
}
}
print_r($newArr);
Output
Array
(
[0-2] => 2
)

Concatenate strings from 2 array based on key

so i have a bit difficulty in combining arrays in php. So let say i have these 2 array
array:4 [▼
20 => "University"
21 => "Polic Station"
22 => "Ambulance"
1 => "Zoo"
]
array:4 [▼
20 => "abc"
21 => "def"
22 => "ghi"
1 => "jkl"
]
How do i actually combine this to this
array:4 [▼
20 => "abc University"
21 => "def Polic Station"
22 => "ghi Ambulance"
1 => "jkl Zoo"
]
Here's the result:
$arr = array(
20=>'University',
21=>'Polic Station',
22=>'Ambulance',
1=>'Zoo');
$arr2= array(
20=>'abc',
21=>'def',
22=>'ghi',
1=>'jkl');
$arr_out = array();
foreach($arr as $key=>$el) {
$arr_out[$key] = $arr2[$key] ." ".$el;
}
var_dump($arr_out);
Obviously, you'll need to keep in mind to check whether the key exists in the second array so you do not get an error when accessing the value.

Fill multidimensional array from other array

I have a multidimensional array $elements where I need to fill it with values from the array $ratings. The array $ratings is built so the first value will fit into the first slot in elements, the next in the second and so on.
$elements
4 => array:3 [▼
2 => 0
3 => 0
4 => 0
]
5 => array:3 [▼
2 => 0
3 => 0
4 => 0
]
7 => array:3 [▼
2 => 0
3 => 0
4 => 0
]
I now need to fill $elements with 9 specific values from
$ratings
array:9 [▼
0 => 3
1 => 2
2 => 1
3 => 3
4 => 3
5 => 2
6 => 3
7 => 2
8 => 1
9 => 3
]
If I manage to loop through $elements, inserting values from $ratings one by one, I will have solved my problem.
So $elements[4][2] should have the value of 3, $elements[4][3] should have value of 2 etc.
Also you can manipulate these by array_fill using loop.
Try this:
<?php
$elements = [
4=>[2=>0, 3=>0, 4=>0],
5=>[2=>0, 3=>0, 4=>0],
7=>[2=>0, 3=>0, 4=>0],
];
$ratings = [ 0 => 3, 1 => 2, 2 => 1, 3 => 3, 4 => 3, 5 => 2, 6 => 3, 7 => 2, 8 => 1, 9 => 3 ];
$ratingsIndex = 0;
foreach(array_keys($elements) as $ElementsIndex) {
foreach(array_keys($elements[$ElementsIndex]) as $ElementsSubIndex) {
$elements[$ElementsIndex][$ElementsSubIndex] = $ratings[$ratingsIndex++];
}
}
echo "<pre>";
print_r($elements);
echo "</pre>";
?>

Categories