Adding an array onto an array - php

i am attempting to make an array:
foreach ($cats as $cat) {
$catsList[$cat->id] = [$cat->info => $cat->info];
}
What i get is a resulting array that only contains the last $cat info.
array:2 [▼
10 => array:1 [▼
23 => 23
]
9 => array:1 [▼
11 => 11
]
]
What i expect to get is:
array:2 [▼
10 => array:1 [▼
23 => 23
15 => 15
12 => 12
]
9 => array:1 [▼
11 => 11
24 => 24
]
]
I guess the syntax is wrong when i'm trying to add a new member and it just overwrites the old one?

Can you try this:
foreach ($cats as $cat) {
$catsList[$cat->id][$cat->info] = $cat->info;
}

Related

php Keeping only 1 date occurence in multi-dimensional array

I have this array with certain brand_ids, within these brands I have an array of dates in which a sale occured but these are based on the products in sale so they may appear multiple times on the same brand_id;
This is my array:
array:5 [▼
2 => array:3 [▼
0 => "2022-05-08"
1 => "2022-05-08"
2 => "2022-05-08"
]
3 => array:5 [▼
0 => "2022-05-08"
1 => "2022-05-08"
2 => "2022-05-08"
3 => "2022-05-08"
4 => "2022-05-08"
]
4 => array:1 [▼
0 => "2022-05-08"
]
1 => array:3 [▼
0 => "2022-05-01"
1 => "2022-05-08"
2 => "2022-05-08"
]
6 => array:3 [▼
0 => "2022-05-08"
1 => "2022-05-08"
2 => "2022-05-08"
]
]
The code to generate this :
pastSales = [];
$historySales = SaleHistoryCount::all()->toArray();
foreach($historySales as $key => $historySale) {
$saleDateToCompare = Carbon::createFromFormat('Y-m-d H:i:s', $historySale['sale_date'])
->format('Y-m-d');
if(in_array($saleDateToCompare , $saleDays)) {
if(! isset($pastSales[$historySale['sale_date']])) {
$pastSales [$historySale['brand_id']][] = Carbon::createFromFormat('Y-m-d H:i:s', $historySale['brand_id'])
->format('Y-m-d');
}
}
}
$saleDays is a 2D array of every sunday untill a certain year like so
[
"2022-05-08"
"2022-05-15"
"2022-05-22"
]
All the duplicates stripped out and have it reduced to one unless the date is different per brand_id but I can't seem to be able to produce that with array_unique, array_mapping and/or array_columns... How would I achieve the output below?
array:5 [▼
2 => array:3 [▼
0 => "2022-05-08"
]
3 => array:5 [▼
0 => "2022-05-08"
]
4 => array:1 [▼
0 => "2022-05-08"
]
1 => array:3 [▼
0 => "2022-05-01"
2 => "2022-05-08"
]
6 => array:3 [▼
0 => "2022-05-08"
]
]
Use in_array as Tim Lewis proposed:
foreach($historySales as $key => $historySale) {
$saleDateToCompare = Carbon::createFromFormat('Y-m-d H:i:s', $historySale['sale_date'])
->format('Y-m-d');
if(in_array($saleDateToCompare , $saleDays)) {
$date_formatted = Carbon::createFromFormat('Y-m-d H:i:s', $historySale['brand_id'])->format('Y-m-d');
// !!! Is this string correct? Maybe we should check for "$historySale['brand_id']" existance?
if(! isset($pastSales[$historySale['sale_date']]))
$pastSales[$historySale['brand_id']] = [];
if( !in_array($date_formatted, $pastSales[$historySale['brand_id']]) )
$pastSales[$historySale['brand_id']][] = $date_formatted;
}
}

how to change array structure in laravel?

Hello everyone i get some problem when try learn php with laravel,
there is the problem ...
i have an array structure like this :
array:3 [▼
0 => 16
1 => 19
2 => 15
]
how can u change the array structure to look like this :
array:3 [▼
0 => array:1 [▼
0 => 16
]
1 => array:1 [▼
0 => 19
]
2 => array:1 [▼
0 => 15
]
]
im newb ,can somebody help me, im using laravel 5.8 ,very grateful if someone helps. sorry for my broken english.
i found it !
use array_chunck()
$convert = array_chunk($data, 1);
dd($convert);
output:
array:3 [▼
0 => array:1 [▼
0 => 16
]
1 => array:1 [▼
0 => 19
]
2 => array:1 [▼
0 => 15
]
]

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();

Merge 2 arrays by their index in each row [duplicate]

This question already has answers here:
PHP's array_merge_recursive behaviour on integer keys
(5 answers)
Closed 5 months ago.
I have 2 arrays, each will always have the same number of rows and same number of values per row.
I need to merge the 2 arrays together, to combine the results on each row, but in a particular way (there will always be only 3 results per row on each array too):
For example, for each row, take the first result of each array, and put them next to each other, then the second result of each array, and put them next to each other, then finally the third.
So Array 1's value will always precede Array 2's value (example shown below):
Array 1:
array:7 [▼
24 => array:3 [▼
0 => 0
1 => 0.66666666666667
2 => 0.66666666666667
]
25 => array:3 [▶]
26 => array:3 [▶]
27 => array:3 [▶]
29 => array:3 [▶]
30 => array:3 [▶]
31 => array:3 [▶]
]
Array 2:
array:7 [▼
24 => array:3 [▼
0 => 0.375
1 => 0.42857142857143
2 => 0.55555555555556
]
25 => array:3 [▶]
26 => array:3 [▶]
27 => array:3 [▶]
29 => array:3 [▶]
30 => array:3 [▶]
31 => array:3 [▶]
]
Intended Combined Array Format:
array:7 [▼
24 => array:6 [▼
0 => 0
1 => 0.375
2 => 0.66666666666667
3 => 0.42857142857143
4 => 0.66666666666667
5 => 0.55555555555556
]
25 => array:6 [▶] ...
Current loop which returns the incorrect layout:
$results = array();
foreach ($questionDetails as $key => $question) {
for ($i = 0; $i < 3; $i++) {
$results[$key][] = $array1[$key] + $array2[$key];
}
}
Returns:
array:7 [▼
24 => array:3 [▼
0 => array:3 [▼
0 => 0
1 => 0.66666666666667
2 => 0.66666666666667
]
1 => array:3 [▼
0 => 0
1 => 0.66666666666667
2 => 0.66666666666667
]
2 => array:3 [▼
0 => 0
1 => 0.66666666666667
2 => 0.66666666666667
]
]
25 => array:3 [▶]
26 => array:3 [▶]
27 => array:3 [▶]
29 => array:3 [▶]
30 => array:3 [▶]
31 => array:3 [▶]
]
I'm unsure why my loop isn't just adding the three values from each row together - but then I think they still won't be in the right order, but I'm unsure of how to approach this.
Many thanks.
This is the "unfancy" (but save) solution if I understand your question correctly - all keys are preserved an set as desired:
$array1;
$array2;
$results = array();
foreach ($questionDetails as $key => $question1) {
$question2 = $array2[$key];
$tp = array();
$tp[0] = $question1[0];
$tp[1] = $question2[0];
$tp[2] = $question1[1];
$tp[3] = $question2[1];
$tp[4] = $question1[2];
$tp[5] = $question2[2];
$results[$key] = $tp;
}
EDIT: There is a way more flexible way to implement this where the number of arguments may vary (see PHP: array_merge() in alternate order (zip order)?).
$array1;
$array2;
function array_zip(...$arrays) {
return array_merge(...array_map(null, ...$arrays));
}
$results = array();
foreach ($questionDetails as $key => $question1) {
$results[$key] = array_zip($question1,$array2[$key]);
}
I would do this:
$combined = array();
foreach($array1 as $key => $value){
$combined[$key] = array();
foreach($value as $key2 => $value2){
$combined[$key][] = $value2;
$combined[$key][] = $array2[$key][$key2];
}
}
For a variable number of records.

Php sorting based on ID and ParentID

i have the following array structure:
| ID | CategoryName | ParentID
_________________________________
1 | Movies | -1
_________________________________
2 | Series | -1
_________________________________
3 | ActionMovies | 1
_________________________________
4 | HorrorMovies | 1
_________________________________
5 | ComedySeries | 2
_________________________________
6 | TVShows | -1
My goal is to reach the following structure
Goal:
| ID | CategoryName | ParentID
_________________________________
1 | Movies | -1
_________________________________
3 | ActionMovies | 1
_________________________________
4 | HorrorMovies | 1
_________________________________
2 | Series | -1
_________________________________
5 | ComedySeries | 2
_________________________________
6 | TVShows | -1
Or explained in word:
Parent-Categories have ParentID = -1 (Example Movies)
All categories keep their original ID-Number
Should come listed directly after their ParentCategory (Example ActionMovies)
RootCategories without Children, come listed at the end of array. (Example TVShows)
How can i achieve this best with PHP? I have no access to the original Mysql query, so that is not an option :)
i have started with this code, but i am not sure it is the right path, and with minimal efforts/readability
$tmpList = Categories_Models_Main::getAllCategories();
$categoryData = array();
foreach ($tmpList as $index => $categoryObject) {
$categoryData[] = array('id' => $categoryObject->id,
'CategoryName' => $categoryObject->parentId,
'name' => $categoryObject->name);
}
///let us assume $categoryData is original state.
///Beginning of manipulation and re-sorting of $tmpList
foreach ($categoryData as $key => $value) {
$mainId[$key] = $value['id'];
$parentId[$key] = $value['parentId'];
}
array_multisort($parentId, $mainId, $categoryData);
Split the main array into two, one with those nodes that doesn't have childs and other with rests of items.
Do the sorting into array of items with array_multisort function and do too a sorting into array of categories without childs using the criteria that you want. The final step will be push the array without childs to the other.
This form isn't the most efficient, but to have a first approach is valid, after this, you can dispense time optimizing the code.
$input = array(
array("foo", "bar", "5"),
array("barr", "baz", "9"),
array("nyan", "nyu", "2")
);
usort($input, function($a, $b) {
if($a[2] < $b[2]) {
return -1;
} else if($a[2] > $b[2]) {
return 1;
} else {
return 0;
}
});
var_dump($input);
Do you mean something like this? The idea is to manually compare the contents of the array using condition you know. Since the thing what is to be sorted is unique, the logic how to sort must be always implemented. With PHP, PHP’s sorting functions most of time does it correctly.
I am pretty sure that this does not answer your question, but might give you some ideas how to make your life easier. This is javascript approach of the problem, but this way you won't even have to think about sorting anything. You just provide parents and children and it is sorted for you and ready to use. A pretty nice way in my opinion. Yet it is probably irrelevant to what you are trying to do, but maybe for some other similar problem you would see this as a solution: https://developers.google.com/chart/interactive/docs/gallery/orgchart
The only way to solve this problem is by using a bottom up approach (i am referring to the pyramids).
Explanation
We need to start with rows (entries) within an array that do not have parents. In my case, it's any element that has "parent_id = 0". Once we have those, we need to build children elements for each parent element.
The latter part would be done recursively by calling sorting method until the element which we are processing has not children. The results from the sorting method are passed down to the previous array point until the array is complete.
Code
Class Categories {
private $cats;
public function getAllCategoriesSorted() {
/**
* $this->cats = [
* 'id' => x, 'parent_id' => x
* ];
*/
$this->cats = Category::get()->toArray();
# find categories with no parents
$keys = array_keys(array_column($this->cats, 'parent_id'), 0);
$return = [];
# loop through each and populate each one
foreach ($keys as $key) {
$return[$this->cats[$key]['id']] = $this->sortCategories($this->cats[$key]);
}
dd($return);
}
private function sortCategories($currentElement) {
# we need to check if current element has any children
$keys = array_keys(array_column($this->cats, 'parent_id'), $currentElement['id']);
if ($keys === false || empty($keys)) {
# we are dealing with childless element, we should return it as it is
return $currentElement;
}
# we are dealing with element that has children, we need to loop through each child
$currentElement['children'] = [];
foreach ($keys as $key) {
$currentElement['children'][$this->cats[$key]['id']] = $this->sortCategories($this->cats[$key]);
}
return $currentElement;
}
}
Example result
array:2 [▼
65 => array:4 [▼
"id" => 65
"name" => "Parent 1"
"parent_id" => 0
"children" => array:14 [▼
66 => array:4 [▼
"id" => 66
"name" => "Child 1"
"parent_id" => 65
"children" => array:22 [▶]
]
87 => array:4 [▼
"id" => 87
"name" => "Child 2"
"parent_id" => 65
"children" => array:31 [▶]
]
117 => array:4 [▶]
118 => array:4 [▶]
120 => array:4 [▶]
124 => array:4 [▶]
125 => array:4 [▶]
127 => array:4 [▶]
225 => array:4 [▶]
305 => array:4 [▶]
434 => array:4 [▶]
321 => array:4 [▶]
348 => array:4 [▶]
468 => array:4 [▶]
]
]
64 => array:4 [▼
"id" => 64
"name" => "Parent 2"
"parent_id" => 0
"children" => array:5 [▼
128 => array:4 [▶]
132 => array:4 [▼
"id" => 132
"name" => "Child 3"
"parent_id" => 64
"children" => array:22 [▼
202 => array:3 [▶]
203 => array:3 [▼
"id" => 203
"name" => "Child 4"
"parent_id" => 132
]
204 => array:3 [▶]
205 => array:3 [▶]
206 => array:3 [▶]
207 => array:3 [▶]
208 => array:3 [▶]
209 => array:3 [▶]
210 => array:3 [▶]
211 => array:3 [▶]
212 => array:3 [▶]
213 => array:3 [▶]
214 => array:3 [▶]
215 => array:3 [▶]
216 => array:3 [▶]
217 => array:3 [▶]
218 => array:3 [▶]
220 => array:3 [▶]
221 => array:3 [▶]
222 => array:3 [▶]
223 => array:3 [▶]
224 => array:3 [▶]
]
]
134 => array:4 [▶]
394 => array:4 [▶]
454 => array:4 [▶]
]
]
]

Categories