Undefined offset on comparing elements in foreach loop - php

Hi I'm trying to compare the dates of 2 elements using a foreach loop. Whenever they match add them to an array and push that array into another one.
The idea for this is that I'll show them all in a table, matching element-dates will have their date column grouped (colspan=n). Using a secondary array I'll be able to use the length of that array as colspan amount.
$elements = array();
$ts_index = 0;
foreach($timesheetweeks as $timesheetweek){
$arr = array();
foreach($timesheetweek->timesheets as $index => $timesheet){
$this_date = $timesheetweek->timesheets[$index]->start_date;
$next_date = $timesheetweek->timesheets[$index + 1]->start_date;
if($this_date == $next_date){
$elements[$ts_index][] = $timesheetweek->timesheets[$index + 1];
} else {
$elements[$ts_index] = $timesheetweek->timesheets[$index];
$ts_index += 1;
}
}
}
Unfortunatly after some headaches and a lost match against Argentinia I get the following error:
Undefined offset: 4
fyi: this is what I try to achieve:
elements [
1 => element1, //diff date
2 => array( //same date array
element2,
element3
),
3 => element4 //diff date
]

Not totally sure about some of the code but this general idea should help:
$elements = array();
$ts_index = -1;
$currentDate = '';
foreach ($timesheetweeks as $timesheetweek) {
foreach ($timesheetweek->timesheets as $index => $timesheet) {
if ($timesheet->start_date != $currentDate) {
// check to see if the last $elements element had just one entry, if so flatten it
if ($ts_index > -1 && count($elements[$ts_index]) == 1) {
$elements[$ts_index] = $elements[$ts_index][0];
}
$currentDate = $timesheet->start_date;
$ts_index++;
// create a new array to store this timesheet and any more that may have the same start_date
$elements[$ts_index] = array();
}
$elements[$ts_index][] = $timesheet;
}
}
// if the last element we added is an array with 1 item, flatten it
if ($ts_index > -1 && count($elements[$ts_index]) == 1) {
$elements[$ts_index] = $elements[$ts_index][0];
}

The item $timesheetweek->timesheets[$index + 1] does not exist when $index reaches its maximium value $index = count($timesheetweek->timesheets) -1;.

Related

Remove duplicate values just once and then sum array

I want to leave duplicates inside my array and only delete one occurrence when a value is found more than once.
Given an array of:
$array = ['+5', '+5', '+3', '+3', '+3', '+3', '+5', '+5'];
+5 and +3 each occur four times. I want to remove just one of the +5 values and just one of the +3 values, then find the sum of the remaining values.
$duplicate = ['+5', '+3'];
$array = ['+5', '+5', '+3', '+3', '+3', '+3', '+5', '+5'];
$i = 0;
foreach ($duplicate as $dup) {
if (strpos($duplicate[$i], '+') !== false) {
$duplicate[$i] = preg_replace('/[^0-9,:]/', '', $duplicate[$i]);
$duplicate[$i] = "-$duplicate[$i]";
}
$i++;
}
$sum = array_merge($duplicate, $array);
$end_value = array_sum(array_values($sum));
var_export($end_value);
For my input, the final sum should be 24 (15 + 9).
You need to remember what value you deleted from the array.
In below script you save te value if it apperas at the first time, in $existsValues array. If you find the same value again you delete it (and save information that you did it in $deletedValues array). If value exists in both arrays then you just do nothing with it. In this way you delete always the second occurence of the value and nothing more.
$existsValues = [];
$deletedValues = [];
foreach ($add_array as $key => $value) {
if (!in_array($value, $existsValues)) {
$existsValues[] = $value;
} else {
if (!in_array($value, $deletedValues)) {
$deletedValues[] = $value;
unset($add_array[$key]);
}
}
}
The task of summing all values and omitting just one occurrence of all repeated values can be done without conditionally maintaining a duplicate array and definitely doesn't require regex.
Code: (Demo)
$array = ['+5', '+5', '+3', '+3', '+3', '+3', '+5', '+5'];
foreach (array_count_values($array) as $value => $count) {
if ($count > 1) {
unset($array[array_search($value, $array)]);
}
}
var_export(array_sum($array)); // 24
The above groups values and counts their occurrences. Then it removes just one of the values when the values occurs more than once. Then sum the altered array.
Or you can boil it down to a mathematical process: (Demo)
$total = 0;
foreach (array_count_values($array) as $value => $count) {
$total += $value * ($count - ($count > 1));
}
echo $total;
// 24
^ if the count is greater than 1, subtract 1 from the multiplier. (if $count > 1, then true is treated as 1; otherwise 0).

Laravel monthly count record

I want to create monthly statistics using Chartjs by Laravel.
$monthly_uploaded_product = DB::table('author_product')
->select(DB::raw('count(id) as total'), DB::raw('MONTH(created_at) as month'))
->groupBy('month')
->get();
the result of query is:
[{"total":1,"month":10},{"total":17,"month":11}]
the output of code should be like this to be represented in Javascript (Chartjs):
[0,0,0,0,0,0,0,0,0,1,17,0]
I have wrote code to generate the array, but error Undefined offset: 1 :
$statistics_monthly_product = array();
foreach (range(1, 12) as $month) {
foreach ($monthly_uploaded_product as $key) {
if ($statistics_monthly_product[$month] == $key->month){
$statistics_monthly_product[$month] = $key->total;
}else{
$statistics_monthly_product[$month] = 0;
}
}
}
You can try something like this:
$year = [0,0,0,0,0,0,0,0,0,0,0,0];//initialize all months to 0
foreach($monthly_uploaded_product as $key)
$year[$key->month-1] = $key->total;//update each month with the total value
}
This code returns your expected array
$data = [["total" => 1,"month" => 10],["total" => 17,"month" => 11]];
$monthTotals = [];
foreach($data as $item){
$monthTotals[$item["month"]] = $item["total"];
}
$chartJSCompat = [];
for($i = 0;$i < 12;$i++){
if(isset($monthTotals[$i+1]))
$chartJSCompat[$i] = $monthTotals[$i+1];
else
$chartJSCompat[$i] = 0;
}
var_dump($chartJSCompat);
The line $statistics_monthly_product = array(); creates a new array. Meaning that when you loop later on and try to do $statistics_monthly_product[$month] you are trying to access the index $month of an empty array. This will always give you the error of undefined index, since there is nothing in the array at all.
Perhaps you can initialize the array first with some default values:
$statistics_monthly_product = [0,0,0,0,0,0,0,0,0,0,0,0];

php, total count of a key with multi value inside a foreach (for) loop

From an REST api, I convert the json data to array data by using
$return= json_decode($response, true);
There are 2 values for the same key inside each array, example:
['some1']=>array(
[0]=> array(['data']=>0)
[1]=> array(['data']=>1)
)
..
I did a for-loop to display the value of ['data'] in which the result are 0 or 1. Now I want to count the total 0 or 1 for ['data'] inside the whole array. How can I do that?
This is my for-loop looks like:
for ($i = 0; $i < count($return['some1']); $i++){
echo $return['some1'][$i]['data'] ."<br/>" ;}
echo shows:
0
1
Thanks,
Simply extract the data column and count the values. The key will contain the value (0 or 1) and the value will contain the count:
$counts = array_count_values(array_column($return['some1'], 'data'));
echo $counts[0]; // return the count of 0s
echo $counts[1]; // return the count of 1s
If you had 2s in there then $counts[2] would contain a count of them etc...
$count_0 = 0;
$count_1 = 0;
for ($i = 0; $i < count($return['some1']); $i++){
if ($return['some1'][$i]['data'] == 0) {
$count_0++;
}
if ($return['some1'][$i]['data'] == 1) {
$count_1++;
}
}
echo $count_0;
echo '<br/>';
echo $count_1;
If you want to know how many times each value of 'data' is repeated you can use something like below to keep track:
// Your input data
$data = array(
'some1' => array(
array('data' => 0),
array('data' => 1),
array('data' => 1),
array('data' => 1),
array('data' => 0)
)
);
// Store the result
$result_array = array();
// Count each unique value for 'data'
foreach ($data['some1'] as $key => $value) {
if ( ! isset($result_array[$value['data']])) {
$result_array[$value['data']] = 0;
}
$result_array[$value['data']]++;
}
// Display unqiue results & their respective counts
print_r($result_array);
Example: https://eval.in/862097

How to substract in one array

I am still beginner.
I want to subtract a value in an array, then I want to compare values. I have an array, the values are not known, depend on the result of a function.
Example :
$value = [5,8,13,15];
I want to subtract each value and save it in an array. Example :
8-5 = 3
13-8 = 5
15-13 = 2
then I want to compare each value (3, 5, 2), which one is bigger.
Please help me. Thank you before.
$value = [5,18,13,15];
sort($value); //to not get negative results
$loop = 0;
$results = array();
while ($loop < count($value))
{
if ($loop == 0)
{
$loop++;
}
else
{
$firstval = $value[$loop];
$secondval = $value[$loop-1];
$results[] = intval($firstval) - intval($secondval);
$loop++;
}
}
sort($results);
$thebiggestkey = $results[count($results)-1];
This should do it for you
A small example with Indexes and Array, if you here is wishes it you can use Foreach to subtract all that there is in the Array
( http://php.net/manual/en/control-structures.foreach.php )
$value = [5,8,3,13,15];
$rep = $value[0] - $value[1];
//5 - 8
echo $rep;
//return -3

Converting 1D array to a 2D array with count of elements [duplicate]

This question already has answers here:
How to count the consecutive duplicate values in an array?
(6 answers)
Closed last month.
I'm stuck and am wondering if someone could point me in the right direction.
I have an array containing numbers, eg:
$start = array(0,0,0,45,45,0,3,0,0,1,1,1,1);
And would like that array to convert to this array:
$result = array( array('id'=>0, 'aantal'=>3,
array('id'=>45,'aantal'=>2),
array('id'=>0, 'aantal'=>1),
array('id'=>3,'aantal'=>1),
array('id'=>0, 'aantal'=>1),
array('id'=>1,'aantal'=>4)
)
I tried traversing the $start array, but I got stuck onlooking up the n-1 in $start without having the key.
Does anyone have any advice on how I can do this?
This would be the typical approach for run length encoding an array of items:
$array = array(0,0,0,45,45,0,3,0,0,1,1,1,1);
$last = null;
$current = null;
$result = array();
foreach ($array as $item) {
if ($item == $last) {
// increase frequency by 1
++$current['aantal'];
} else {
// the first iteration will not have a buffer yet
if ($current) {
$result[] = $current;
}
// create buffer array item, set frequency to 1
$current = array('id' => $item, 'aantal' => 1);
$last = $item;
}
}
// last pass
if ($current) {
$result[] = $current;
}

Categories