Array values replaced rather than pushed - php

I'm trying to build a multidimensional array like array(years => array(months)). Each new month added to a year replaces the old month value in the year array rather than appending the value.
<?php
$dates = array();
foreach (Blog::all() as $blog) {
$date_year = date("Y", strtotime($blog->created_at));
$date_month = date("F", strtotime($blog->created_at));
if (!in_array($date_year, $dates)) {
$dates[$date_year] = array();
}
if (!in_array($date_month, $dates[$date_year])) {
$dates[$date_year][] = $date_month;
print $date_year." ".$date_month."<br>";
}
}
print_r($dates); ?>
Outputs:
Array ( [2009] => Array ( [0] => December ) [2010] => Array ( [0] => March ) [2011] => Array ( [0] => August ) [2012] => Array ( [0] => November ) [2013] => Array ( [0] => October ) [2014] => Array ( [0] => April ) )
The months displayed are the last month available for each year. I have also tried with array_push($dates[$date_year], $date_month) for the same result.

The year array is being overwritten each time here:
if (!in_array($date_year, $dates)) {
$dates[$date_year] = array();
}
Check the array keys instead of the array values with array_key_exists:
if (!array_key_exists($date_year, $dates)) {
$dates[$date_year] = array();
}
Or, better yet IMO, use isset as suggested by vp_arth below. (For succintness.)
if (!isset($dates[$date_year])) {
$dates[$date_year] = array();
}

Related

Merge two multidimensional arrays into one in Php

Hi I have two multidimensional arrays in PhP and I am trying to create a new array which is flatter.
The first array is called weeksBooked and has a structure like below:
Array
(
[0] => Array
(
[periodweekno] => 27
)
[1] => Array
(
[periodweekno] => 28
)
[2] => Array
(
[periodweekno] => 29
)
)
The second one is called bookings . This stores the day a child was booked for that particular week.
Array
(
[0] => Array
(
[periodDayName] => Monday
)
[1] => Array
(
[periodDayName] => Tuesday
)
[2] => Array
(
[periodDayName] => Thursday
)
[3] => Array
(
[periodDayName] => Friday
)
)
I am trying to merge both the arrays and check if the perioddayName is Monday then in the "new" merged array I can show it as "monday"=> 0 and if not then show it as "monday"=> 1. I would like to repeat it for each "workday (i.e. monday - friday).
I apologise in advance if I am not explaining it well but this is what I am trying to achieve is a structure that I can bind to a table:
{Weekno:27, Monday:1,Tuesday:0,Wednedsay:1,Thursday:1,Friday:0
Weekno:28, Monday:0,Tuesday:0,Wednesday:1, Thursday:0,Friday:1}
This is my attempt so far but I just can't get it to flatten it :
$result = array();
foreach ($weeksbooked as $week) {
$sql = "SELECT periodDayName FROM Attendance WHERE weekno = ". $week['periodweekno'];
$bookings = $this->db->RawQuery($sql,null);
// print_r($bookings);
foreach ($bookings as $booking) {
$daysbooked= array();
if($booking['periodDayName'] == 'Monday'){
$daysbooked['monday'] = 0;
}else{
$daysbooked['monday'] = 1;
}
if($booking['periodDayName'] == 'Tuesday'){
$daysbooked['tuesday'] = 0;
}else{
$daysbooked['tuesday'] = 1;
}
.....
array_push($weeksbooked,$daysbooked)
}
array_push($result,$weekbooked)
Perhaps something like this?
$result = array();
foreach ($weeksbooked as $week) {
$sql = "SELECT periodDayName FROM Attendance WHERE weekno = ". $week['periodweekno'];
$bookings = $this->db->RawQuery($sql,null);
// print_r($bookings);
$thisweek = array('Weekno' => $week['periodweekno'],
'Monday' => 0,
'Tuesday' => 0,
'Wednesday' => 0,
'Thursday' => 0,
'Friday' => 0
);
foreach ($bookings as $booking) {
$thisweek[$booking['periodDayName']] = 1;
}
$result[] = $thisweek;
}
print_r($result);
It should produce an output something like what you are looking for. Without the raw data in a table it's hard to be certain.

Sum the value of single array based on key value

This question is not a duplicate of other. it is different,This is current code, I am trying to sum the values of a array based on the same key value of date.
foreach ($TablesArr as $tr) {
$criteria = new CDbCriteria;
$criteria->select = 'date,mal';
$Arr1 = $tr::model()->findAll($criteria);
$array_1 = array();
foreach ($Arr1 as $a1) {
$array_1['date'] = $a1['date'];
$array_1['mal'] = $a1['mal'];
}
}
My Current output is:
Array
(
[date] => 2015-11-00
[mal] => 35
)
Array
(
[date] => 2015-12-00
[mal] => 20
)
Array
(
[date] => 2016-01-00
[mal] => 30
)
Array
(
[date] => 2016-01-00
[mal] => 10
)
Array
(
[date] => 2015-11-00
[mal] => 50
)
If the date is same, then sum the value of mal in the array. For example, In the above array, the date 2015-11-00 appears twice or more than twice (5 or 10 times etc) then sum all of the values of it for that date. Currently it appears twice so for 2015-11-00 the mal values will be 35+50=85. I want my output to be like this below:
Array
(
[date] => 2015-11-00
[mal] => 85
)
Array
(
[date] => 2015-12-00
[mal] => 20
)
Array
(
[date] => 2016-01-00
[mal] => 40
)
I have tried:
$result = array();
foreach($Arr1 as $data) {
$result[ $data['date'] ] += $data['mal'];
}
Your $array_1 variable doesn't contain all the values from the original $Arr1 array. You're overwriting the same elements each time through the loop, so it just contains the last item from $Arr1. These lines:
$array_1['date'] = $a1['date'];
$array_1['mal'] = $a1['mal'];
should be:
$array_1[] = array('date' => $a1['date'], 'mal' => $a1['mal']);
Another problem is that you're resetting $array_1 each time through the outer loop.
You can also use array_merge to combine the arrays, instead of the loop:
$array_1 = array();
foreach ($TablesArr as $tr) {
$criteria = new CDbCriteria;
$criteria->select = 'date,mal';
$Arr1 = $tr::model()->findAll($criteria);
$array_1 = array_merge($array_1, $Arr1);
}
You can use one of the solutions in php group by SUM using multi dimensional array to create an associative array with the sums grouped by date. You can turn this into a 2-dimensional array with another loop:
$newresult = array();
foreach ($result as $date => $mal) {
$newresult[] = array('date' => $date, 'mal' => $mal);
}
DEMO

put values from query into array

I need values from my database to plot a graph.
I have multiple lines I want to plot on the same graph.
I need the values, for each line, in the following form, for as many different $dates there are in the database:
$graph_points1 = array(array($date, $value), array($date, $value), array($date, $value));
I have a query to get the data from the database:
$data = $wpdb->get_results($wpdb->prepare( "SELECT * FROM `wp_graph_info` ORDER BY DATE ASC"));
If I use the following code:
foreach($data as $datas){
$list_name = $datas->list_name;
$date = $datas->date;
$value = $datas->subscriber_count;
if($list_name == 'line1'){
$result = array(array($date,$value));}}
print_r($result); will give:
Array ( [0] => Array ( [0] => 2015-05-16 [1] => 131 ) )
Array ( [0] => Array ( [0] => 2015-05-17 [1] => 133 ) )
Array ( [0] => Array ( [0] => 2015-05-18 [1] => 137 ) )
which is almost what I want.
I need to have the results as:
$graph_points1 = array(array(2015-05-16, 131), array(2015-05-17, 133), array(2015-05-18, 137));
how to I put it in the above form?
Also I can't plot the date on the x-axis. How do I only retrieve the 'day' value so I have:
$graph_points1 = array(array(16, 131), array(17, 133), array(18, 137));
Also if there a way to loop through all th $list_names (I have 7 different lists, so my graph will plot 7 lines) or do I need to use an if() statement for each one?
$result = [];
foreach($data as $datas){
$list_name = $datas->list_name;
$date = $datas->date;
$value = $datas->subscriber_count;
list($year, $month, $day) = explode('-', $date);
$result[$list_name][] = array($day,$value);
}
echo "<pre>";var_dump($result);echo "</pre>";

Two dimensional PHP array not outputting correctly

I have the following array of dates and places - basically each date will need to allow for multiple places. I am trying to display the array below into something like the following format:
20140411
Basingstoke
Salisbury
20140405
Basingstoke
20140419
Salisbury
... and so on
The array:
Array
(
[20140411] => Array
(
[0] => Array
(
[0] => Basingstoke
)
[1] => Array
(
[0] => Salisbury
)
)
[20140405] => Array
(
[0] => Array
(
[0] => Basingstoke
)
)
[20140419] => Array
(
[0] => Array
(
[0] => Salisbury
)
)
[20140427] => Array
(
[0] => Array
(
[0] => Basingstoke
)
)
)
I believe I'm close, but I have always had some sort of mental block when it comes to working with arrays/keys etc. I am trying to do a nested foreach loop, which displays the dates fine, but am just getting "Array" outputted for the locations:
foreach ($dates as $date => $dateKey) {
// Format the date
$theDate = DateTime::createFromFormat('Ymd', $date);
$theFormattedDate = $theDate->format('d-m-Y');
echo '<h4>'.$theFormattedDate.'</h4>';
foreach ($dateKey as $key => $venue) {
echo $venue;
}
}
Can someone spot where I'm going wrong here?
EDIT:
Here is where the arrays are being created, if that helps?
$dates = array();
while ( have_rows('course_date') ) : the_row();
$theVenue = get_sub_field('venue');
// Use the date as key to ensure values are unique
$dates[get_sub_field('date')][] = array(
$theVenue->post_title
);
endwhile;
In your case venue is an array.
It's always an array with the only element you can address as [0].
Thus...
foreach ($dates as $date => $dateKey) {
// Format the date
$theDate = DateTime::createFromFormat('Ymd', $date);
$theFormattedDate = $theDate->format('d-m-Y');
echo '<h4>'.$theFormattedDate.'</h4>';
foreach ($dateKey as $key => $venue) {
echo $venue[0];
}
}
Or, in case you can have multiple venues in that last-level array, you can re-write the inner foreach adding another one:
foreach ($dates as $date => $dateKey) {
// Format the date
$theDate = DateTime::createFromFormat('Ymd', $date);
$theFormattedDate = $theDate->format('d-m-Y');
echo '<h4>'.$theFormattedDate.'</h4>';
foreach ($dateKey as $key => $venues) {
foreach($venues as $v) {
echo $v;
}
}
}
Places are nested 1 level deeper, you need one more foreach.
Never mind, that other guy said this plugin is supposed to work like that :)

want to combine multiple array in php

i want to do this type
in my form i have check box array and the function i want to call as the size of check box array,
now all is ok simple one time calling.
but i want to call the function as above,
and store the function return value in one array
as function return array so i want to do like
this
for user id 1->callfunction return array
user id 2->callfunction return array
....
....
i have try to used the array_push but i does not get any result
here is my code
$track = array();
for($i=0;$i<sizeof($usr);$i++)
{
if (!empty($start) and !empty($end))
{
$track_e = $tracker->getProjectTrack($id, $usr[$i], $taski, $start, $end);
//$track = $tracker->getProjectTrack($id, $usr, $taski, $start, $end);
}
$track=array_push($track,$track_e);
}
if you want to go through array, use foreach
$track = array();
if (!empty($start) and !empty($end)){
foreach ($usr as $u){
array_push($track,$tracker->getProjectTrack($id, $u, $taski, $start, $end);
}
}
Solution:
$track=array_push($track,$track_e);
array_push doesn't return an array; it returns the new number of elements in the array, modifying the array it receives as an argument in-place. It's actually much easier to just write:
$track []= $track_e;
Suggestion:
for($i=0;$i<sizeof($usr);$i++) {
# ...
$track_e = $tracker->getProjectTrack($id, $usr[$i], $taski, $start, $end);
Why not simplify the process of indexing $usr and counting the number of elements in it like so:
foreach ($usr as $usr_elem) {
# ...
$track_e = $tracker->getProjectTrack($id, $usr_elem, $taski, $start, $end);
Array ( [0] => Array ( [0] => 5 ) [1] => Array ( [0] => 6 ) [2] => Array ( [0] => 7 ) )
instead of this it returns
Array ( [0] => Array ( [0] => Array ( [0] => 7 ) ) [1] => Array ( [0] => Array ( [0] => 9) ) )
something like that
so i want to return it in as same first one.

Categories