Restructuring PHP array - php

I have tried many different variation, but cannot get the right structure. Maybe, you expert might what to give it a try.
What I need to do is return the therapist who may have multiple children assigned to him. It will return the children's schedules that are assigned to him.
I have tried the following Code. This is the closest I can get to the format I need.
// Grab the therapist
$therapist = $this->Therapist->find('first', array('conditions' => array('Therapist.' . $this->Therapist->primaryKey => $id)));
// Grab the child(ren) assigned to the therapist
// Returns id as key and name as value.
$children = $this->Child->get_children($id);
$schedule = array();
// Loop through the assigned children and get the id (key).
foreach($children as $key => $value):
// Loop through and grab all the scheduled days and times for child(ren).
foreach($this->Schedule->get_full_schedule($key) as $child):
// Have the child name at the top of the array.
if($name != $child['Child']['child_name']):
$schedule[] = array_push($schedule, array('child_name' => $child['Child']['child_name']));
$name = $child['Child']['child_name'];
endif;
// Get all the scheduled days for the child and add to array.
if($child['Schedule']['child_id'] == $child['Child']['id']):
$schedule[]['Schedule'] = $child['Schedule'];
endif;
endforeach;
endforeach;
Which outputs the following Array:
Array
(
[0] => Array
(
[child_name] => John Smith
)
[1] => 1
[2] => Array
(
[Schedule] => Array
(
[id] => 19
[child_id] => 197
[days] => Monday
[start_time] => 17:00:00
[end_time] => 22:00:00
)
)
[3] => Array
(
[child_name] => Jane Smith
)
[4] => 4
[5] => Array
(
[Schedule] => Array
(
[id] => 16
[child_id] => 138
[days] => Monday
[start_time] => 09:00:00
[end_time] => 17:00:00
)
)
[6] => Array
(
[Schedule] => Array
(
[id] => 17
[child_id] => 138
[days] => Sunday
[start_time] => 09:00:00
[end_time] => 12:00:00
)
)
[7] => Array
(
[Schedule] => Array
(
[id] => 18
[child_id] => 138
[days] => Tuesday
[start_time] => 09:00:00
[end_time] => 17:00:00
)
)
)
What I would like is:
Array
(
[0] => Array
(
[child_name] => John Smith
[0] => Array
(
[Schedule] => Array
(
[id] => 19
[child_id] => 197
[days] => Monday
[start_time] => 17:00:00
[end_time] => 22:00:00
)
)
)
[1] => Array
(
[child_name] => Jane Smith
[0] => Array
(
[Schedule] => Array
(
[id] => 16
[child_id] => 138
[days] => Monday
[start_time] => 09:00:00
[end_time] => 17:00:00
)
)
[1] => Array
(
[Schedule] => Array
(
[id] => 17
[child_id] => 138
[days] => Sunday
[start_time] => 09:00:00
[end_time] => 12:00:00
)
)
[2] => Array
(
[Schedule] => Array
(
[id] => 18
[child_id] => 138
[days] => Tuesday
[start_time] => 09:00:00
[end_time] => 17:00:00
)
)
)
Any help is appreciated.
Thank,
Greg

Have you thought about just using Containable Behavior? Seems MUCH easier than the way you're trying to do it:
$this->Therapist->find('first', array(
'conditions' => array(
'Therapist.' . $this->Therapist->primaryKey => $id
),
'contain' => array(
'Child' => array(
'Schedule'
)
)
));
Not only is it a lot easier, but your data should come back in an acceptable and nested format.

Related

How to Compare two multidimensional associative arrays with differen items count

I have two multidimensional associative arrays with differen items count.
Important is that I don't know which aray will have more elements (A or B)
First array (A):
[0] => Array
(
[catID] => 65
[discount] => 10
[productID] => Array
(
[0] => 10887
[1] => 8508
[2] => 8350
)
[startDate] => 05/12/2022 12:00 am
[endDate] => 10/12/2022 12:00 am
)
[1] => Array
(
[catID] => 66
[discount] => 10
[productID] => Array
(
[0] => 13184
[1] => 10707
[2] => 8350
)
[startDate] => 10/12/2022 12:00 am
[endDate] => 15/12/2022 12:00 am
)
Second array (B):
[0] => Array
(
[catID] => 72
[discount] => 15
[productID] => Array
(
[0] => 16239
[1] => 16236
[2] => 10887
[3] => 13184
[4] => 8524
[5] => 13314
)
[startDate] => 12/12/2022 12:00 am
[endDate] => 15/12/2022 12:00 am
)
After compare these arrays (A, B) I'd like to retrive something like that:
Array A(remove productID if exists in array B):
[0] => Array
(
[catID] => 65
[discount] => 10
[productID] => Array
(
[1] => 8508
[2] => 8350
)
[startDate] => 05/12/2022 12:00 am
[endDate] => 10/12/2022 12:00 am
)
[1] => Array
(
[catID] => 66
[discount] => 10
[productID] => Array
(
[0] => 10707
)
[startDate] => 10/12/2022 12:00 am
[endDate] => 15/12/2022 12:00 am
)
Array B(no changes):
[0] => Array
(
[catID] => 72
[discount] => 15
[productID] => Array
(
[0] => 16239
[1] => 16236
[2] => 10887
[3] => 13184
[4] => 8524
[5] => 13314
)
[startDate] => 12/12/2022 12:00 am
[endDate] => 15/12/2022 12:00 am
)
Populate a flat "blacklist" array from your second array.
Loop over the first array's rows and filter the productId values against the blacklist array.
Code: (Demo)
$blacklist = array_merge(...array_column($b, 'productID'));
var_export(
array_map(
fn($row) => array_replace($row, ['productID' => array_values(array_diff($row['productID'], $blacklist))]),
$a
)
);
Or if you don't mind a classic foreach(), then this may be easier to read: (Demo)
$blacklist = array_merge(...array_column($b, 'productID'));
foreach ($a as &$row) {
$row['productID'] = array_values(array_diff($row['productID'], $blacklist));
}
var_export($a);

How to delete keys from multi-dimension array dynamically

I have to filter this array to see only future items.
How do I unset items from which the timeEnd has expired?
i.e when I call this array at 17:00 there's only array[2] left.
Array
(
[0] => Array
(
[id] => 3034
[date] => 28-09-2016
[timeStart] => 08:30
[timeEnd] => 09:30
[description] => User_A
[locationId] => 1
[roomId] => 8
[relationId] => 104
)
[1] => Array
(
[id] => 2524
[date] => 28-09-2016
[timeStart] => 08:30
[timeEnd] => 12:00
[description] => User_B
[locationId] => 1
[roomId] => 5
[relationId] => 86
)
[2] => Array
(
[id] => 2533
[date] => 28-09-2016
[timeStart] => 09:00
[timeEnd] => 18:00
[description] => User_C
[locationId] => 1
[roomId] => 4
[relationId] => 31
)
)
foreach ($reservations as $key=>$reservation) {
$expireDate = $reservation['date'].' '.$reservation['timeEnd'];
if (strtotime($expireDate) <= strtotime('now')){
unset($reservations[$key]);
}
}

Merge multidimentional array if parent id same then merge child data

I want to convert below array.
Criteria is,
If projectId same then store same project id data under array of project which contains projectId as key.
Array
(
[0] => Array
(
[PMST] => Array
(
[id] => 4
[project_id] => 25
[task_name] => Final task 3
[start_date] => 2016-06-21 00:00:00
[end_date] => 2016-06-29 00:00:00
)
[PMSP] => Array
(
[id] => 25
[project_name] => Project 3
[start_date] => 2016-06-01 00:00:00
[end_date] => 2016-06-04 00:00:00
)
)
[1] => Array
(
[PMST] => Array
(
[id] => 9
[project_id] => 28
[task_name] => Task Test 333 edit
[start_date] => 2016-06-19 00:00:00
[end_date] => 2016-06-29 00:00:00
)
[PMSP] => Array
(
[id] => 28
[project_name] => Project Employee Test
[start_date] => 2016-06-10 00:00:00
[end_date] => 2016-06-30 00:00:00
)
)
[2] => Array
(
[PMST] => Array
(
[id] => 1
[project_id] => 28
[task_name] => Task 1
[start_date] => 2016-06-01 00:00:00
[end_date] => 2016-06-04 00:00:00
)
[PMSP] => Array
(
[id] => 28
[project_name] => Project Employee Test
[start_date] => 2016-06-10 00:00:00
[end_date] => 2016-06-30 00:00:00
)
)
)
Desire Output
Array
(
[25] => Array
(
[PMSP] => Array
(
[id] => 25
[company_id] => 1114701
[project_name] => Project 3
[start_date] => 2016-06-01 00:00:00
[end_date] => 2016-06-04 00:00:00
)
[taskdetails] => Array
(
[0] => Array(
[PMST] => Array
(
[id] => 4
[project_id] => 25
[company_id] => 1114701
[task_name] => Final task 3
[start_date] => 2016-06-21 00:00:00
[end_date] => 2016-06-29 00:00:00
)
)
)
)
[28] => Array
(
[PMSP] => Array
(
[id] => 28
[company_id] => 1114701
[project_name] => Project Employee Test
[start_date] => 2016-06-10 00:00:00
[end_date] => 2016-06-30 00:00:00
)
[taskdetails] => Array
(
[0] => Array
(
[PMST] => Array
(
[id] => 9
[project_id] => 28
[company_id] => 1114701
[task_name] => Task Test 333 edit
[start_date] => 2016-06-19 00:00:00
[end_date] => 2016-06-29 00:00:00
)
)
[1] => Array(
[PMST] => Array
(
[id] => 1
[project_id] => 28
[company_id] => 1114701
[task_name] => Task 1
[start_date] => 2016-06-01 00:00:00
[end_date] => 2016-06-04 00:00:00
)
)
)
)
)
Loop over your input array using foreach, adding the PMST data to an output array as you go. It looks like it's safe to assume the PMSP data for two tasks on the same project will be the same.
$output = [];
foreach ($input as $task) {
if (!isset($output[$task["PMSP"]["id"]])) {
$output[$task["PMSP"]["id"]] = ["PMSP" => $task["PMSP"], "taskdetails" => []];
}
$output[$task["PMSP"]["id"]]["taskdetails"][] = $task["PMST"];
}
See the below example
Example
$data = [];
foreach ($a as $b) {
$key = $b["PMSP"]["id"];
if (!isset($data[$key])) {
$data[$key] = ["PMSP" => $b["PMSP"], "taskdetails" => []];
}
$data[$key]["taskdetails"][] = $b["PMST"];
}
echo "<pre>";
print_r($data);exit();
Your latest data
Example 2

how to get value array using key from array

What I want to do
here is the main array
Array
(
[0] => Array
(
[Culture] => Array
(
[id] => 8
[title] => test123
[description] => test123
[year] => 2012
[photo] => test123.JPG
[datetime] => 0000-00-00 00:00:00
[status] => 0
)
)
[1] => Array
(
[Culture] => Array
(
[id] => 9
[title] => here title
[description] => here title
[year] => 2012
[photo] => here.JPG
[datetime] => 0000-00-00 00:00:00
[status] => 0
)
)
[2] => Array
(
[Culture] => Array
(
[id] => 11
[title] => here title 2
[description] => here title 2
[year] => 2012
[photo] => here.JPG
[datetime] => 0000-00-00 00:00:00
[status] => 0
)
)
[3] => Array
(
[Culture] => Array
(
[id] => 12
[title] => here title 3
[description] => here title 3
[year] => 2013
[photo] => here.JPG
[datetime] => 0000-00-00 00:00:00
[status] => 0
)
)
[4] => Array
(
[Culture] => Array
(
[id] => 13
[title] => here title 4
[description] => here title 4
[year] => 2014
[photo] => here.JPG
[datetime] => 0000-00-00 00:00:00
[status] => 0
)
)
[5] => Array
(
[Culture] => Array
(
[id] => 14
[title] => here title 5
[description] => here title 5
[year] => 2015
[photo] => here.JPG
[datetime] => 0000-00-00 00:00:00
[status] => 0
)
)
)
now from this array I want array of year (by key)
like:
Array
(
[0]=>2012
[1]=>2013
[2]=>2014
[3]=>2015
)
Loop through your array and assign those years to a new array with their keys intact.
$years=array();
foreach($yourArray as $key=>$value)
{
$years[$key]=$value["Culture"]["year"];
}
$years = array_unique($years);
print_r($years);
You can first loop through the array with a foreach loop and then use array_unique to get the array of years:
$years = array();
foreach ($records as $record) {
$years[] = $record['Culture']['year'];
}
$years = array_unique($years);
Demo!
$years = [];
foreach($arr as $newarray){
$years[] = $newarray['Culture']['year'];
}
$years = array_unique($years);
The new array years will now hold all the years in the old array. array_unique will get rid of all duplicate years.
My way is to use array-walk that takes anonymous function to fill the array, the solution will be in only one line of code.
Its working for me
foreach($cultures as $row)
{
$year[]=$row['Culture']['year'];
}
$year = array_unique($year);
$year = array_values($year);
echo "<pre>";print_r($year);

Display number of occurrences by day from array of dates

I am working on a statistics application and I want to output the amount of interactions that happened by day.
I have an multidimensional array that pulls all the information from the database, here is an example:
[0] => Array
(
[date] => 2012-07-26
[location] => 709c6d241674ca22
[action] => start_scan
)
[1] => Array
(
[date] => 2012-07-26
[location] => 709c6d241674ca22
[action] => scan_displayed
)
[2] => Array
(
[date] => 2012-07-27
[location] => 709c6d241674ca22
[action] => lower_device
)
[3] => Array
(
[date] => 2012-07-27
[location] => 709c6d241674ca22
[action] => how_to_use_displayed
)
[4] => Array
(
[date] => 2012-07-27
[location] => 709c6d241674ca22
[action] => raise_device
)
[5] => Array
(
[date] => 2012-07-28
[location] => 709c6d241674ca22
[action] => scan_displayed
)
I can work out what day each interaction occurred on by formatting the date:
date('D', strtotime('2012-07-26'));
My question is how do I count how many interactions happened on each day of the week and then output it, something like:
[Sunday] => 2
[Monday] => 3
[Tueday] => 1
[Wednesday] => 5
[Thursday] => 10
[Friday] => 4
[Saturday] => 9
Any suggestions are really appreciated!
$dates = array();
foreach($data as $item) {
$day = date('l', $item['date']);
$dates[$day]++;
}
var_dump($dates);
You may want to declare the array as $dates = array('Monday'=>0, 'Tuesday'=>0 .... ) to get the array containing the days with no interactions.

Categories