calculating the average of last values in PHP using Queue - php

My problem is easy to understand, I need to loop a table and calculate the average of every last 4 value. I try to use Queue to Push the current value and to pop the first value pushed.
I have 2 problem, The Queus works as Stack, when I pop, the last value goes out and not the first one
$q = new SplQueue();
$q->push(1);
$q->push(2);
$q->push(3);
$q->push(4);
$q->push(5);
$q->pop();
I get this Array as ( [0] => 1 [1] => 2 [2] => 3 [3] => 4 ) )
I want this Array as ( [0] => 2 [1] => 3 [2] => 4 [3] => 5 ) )
Second problem, How to use array_sum($q) / $counter[$q]; on Queue ?
Thank you

As it is said in documentation (http://php.net/manual/ro/class.splqueue.php ), if you use push() and pop() it will behave like a stack. Use enqueue() and dequeue()
If you want to get the average of last 4 values, you can create a new array containing the 4 values of your queue dequeue(), then use array_sum($a)/ count($a) on it
If you do not want to create a new array you can simply:
$sum = 0;
$lastElements = 4;
for($i = 0;$i<$lastElements;$i++)
$sum+= $q.dequeue()
echo $sum/$lastElements;
And you can scale this by changing the $lastElements value.The code is not tested

Related

PHP Array length

So this may be a bit long winded to explain, but I'll try to make it concise.
I have a db query that pulls in 3 different Tag IDs, 2 of them are associated to 4 Hub IDs, while 1 is associated with only 3.
I return all tags, and sort the results by ID (so all 4 results for tag 1 are grouped, all 4 of 2, and all 3 of 3) Like so:
Array
(
[0] => 40BD32751DF1
[1] => 40BD32751DF1
[2] => 40BD32751DF1
[3] => 40BD32751DF1
[4] => 10CEA9FD173A
[5] => 10CEA9FD173A
[6] => 10CEA9FD173A
[7] => 10CEA9FD173A
[8] => 10CEA9FCFE26
[9] => 10CEA9FCFE26
[10] => 10CEA9FCFE26
)
Then I do a while loop and loop it for each Tag ID (3x). Inside that, I use array_keys on an array_column search to find the array indexes of each Tag ID, count how many results I have (4, 4, 3) I then take that row's data using the array key, and loop number to push that row of data into an array for later sorting:
while($currentTag = pg_fetch_assoc($tagList)) {
$tkeys = array_keys(array_column($tagDataArray, 'devmac'), $currentTag['devmac']);
$tempArray = array();
for($k=0; $k < count($tkeys); $k++){
array_push($tempArray, $tagDataArray[$tkeys[$k]]);
}
//Then I sort that temporary array so one of the values in the row is the highest:
foreach($tempArray as $sigkey => $sigrow) {
$sigsort[$sigkey] = $sigrow['devrssi'];
}
array_multisort($sigsort, SORT_DESC, $tempArray);
updateArticles($tempArray[0]);
}
Now the problem comes from that temporary array. I have 4 results for the first ID, 4 for the second, then 3 for the third, yet for the third ID, somehow I still get 4 items in the array even though I reinitialize it with each while loop pass (each ID). The fourth result from the second ID, ends up as the fourth result for the third ID.
How is this possible? I've been trying to figure this out for hours and I'm not making any headway. The $tkeys gives me 3 on the third ID, so the for loop runs 3 times, everything makes sense, till the array push where something just decides to stick around. I've even added a print_r to the tempArray and before it runs the third time, it's empty! I dont get where it keeps creeping back in.
Thanks.
Make sure that when you process data in subsequent loops, you remove all previous data...
$sigsort= [];
foreach($tempArray as $sigkey => $sigrow) {
$sigsort[$sigkey] = $sigrow['devrssi'];
}

PHP json_encode switching array to object in a particular server... why?

I have a library that read a directory and join a lot of information in a single object, so I can get it by JSON and work on it with JavaScript. I have a php that calls the lib for me and returns the JSON, simple as this:
echo('&vars_ini=OK&dados='.json_encode($Lista).'&vars_fim=');
After get the value of "dados", this is what I got:
{"erro":"OK","Lista":[{"nome":"a-process.gif","base":"a-process","ext":"gif","bytes":93117,"datac":"07\/04\/2016 13:46","datam":"31\/05\/2017 20:06","timestampc":1460047579,"timestampm":1496272006}, ... etc. there is also other lists as subdirectories.
But in this particular server, I am getting this:
{"erro":"OK","Lista":{"22":{"nome":"a-process.gif","base":"a-process","ext":"gif","bytes":93117,"datac":"03\/08\/2016 18:33","datam":"03\/08\/2016 18:26","timestampc":1470249183,"timestampm":1470248785},"43":{"nome":"g-agenda.gif","base":"g-agenda","ext":"gif","bytes":1454,"datac":"03\/08\/2016 18:33","datam":"03\/08\/2016 18:26","timestampc":1470249183,"timestampm":1470248786}, ... etc.
Instead of "Lista" be rendered with "[", there is a "{". My testing server is running php 5.6.10 and this server is 5.6.27. I don't think is a version problem (really?) but maybe some directive is telling to work like this.
The simple solution is to convert those objects to array, no big deal, but I am trying to understand why this is happening and to optimize my code.
You need to start your array at 0 and increment contiguously to get a JSON array. Failing that, use array_values() to re-index the PHP array before json_encode().
In your first example the array index starts at 0 so json_encode() treats it as an array. In the second the array index starts at 22 so it is treated as an object. The indexes also need to be contiguous to generate an array. Somehow you generate or get different indexes in each instance (maybe sorting or other function that defines or moves the indexes).
This shows contiguous indexes starting at 0:
$v = range(1,5);
print_r($v);
echo json_encode($v);
Yields an array:
Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 4
[4] => 5
)
[1,2,3,4,5]
While starting at 1:
$k = range(1,5);
$z = array_combine($k, $v);
print_r($z);
echo json_encode($z);
Yields an object:
Array
(
[1] => 1
[2] => 2
[3] => 3
[4] => 4
[5] => 5
)
{"1":1,"2":2,"3":3,"4":4,"5":5}
Starting at 0 with non-contiguous indexes:
$z = array(0, 2=>2, 3=>3, 5=>5);
print_r($z);
echo json_encode($z);
Yields an object:
Array
(
[0] => 0
[2] => 2
[3] => 3
[5] => 5
)
{"0":0,"2":2,"3":3,"5":5}

PHP - Multiple Time Difference Calculations

For the life of me I cannot find anywhere on the internet that has any documentation on how to solve my problem. I've seen a massive amount of ways to calculate differences in time but I can not seem to put something together that works for my situation.
I'm currently building a time management/ticket system that is a plugin for WordPress. I am using custom tables and not the WordPress tables. I have a table that contains all the main ticket information and another table that contains all the start/stop times. Once the user marks the ticket as complete it will then take all the start/stop time values and calculate the total time spent and then place that total time value into a "total_time" column in the main ticket table.
I'm querying the database and pulling the start/stop times by using:
$start_times = $wpdb->get_results($start_times_query);
$stop_times = $wpdb->get_results($stop_times_query);
Now I have the information in 2 array's. Is this the way I should be doing this?
The array's give me this (for start times):
Array ( [0] => Array ( [time] => 2016-04-29 12:02:43 ) [1] => Array ( [time] => 2016-04-29 12:04:18 ) [2] => Array ( [time] => 2016-04-29 12:06:07 ) [3] => Array ( [time] => 2016-04-29 12:07:56 ) [4] => Array ( [time] => 2016-04-29 12:10:30 ) [5] => Array ( [time] => 2016-04-29 12:11:59 ) )
(Same format for the end times)
Then I break down the array using:
$startTimes = array_column($startTimes, 'time');
$endTimes = array_column($endTimes, 'time');
Which now gives me this as the array (this one is just the start times, but same format for the end times):
Array ( [0] => 2016-04-29 12:02:43 [1] => 2016-04-29 12:04:18 [2] => 2016-04-29 12:06:07 [3] => 2016-04-29 12:07:56 [4] => 2016-04-29 12:10:30 [5] => 2016-04-29 12:11:59 )
Usually I can do a foreach ($start_time as $time){} to itterate through all the values, but (correct me if I'm wrong) I can't put two array's into the foreach brackets and I can't place another foreach statement in the current one because then it will just return all the times for the second array and only return one value for the first array. I feel like I'm missing something simple, what can I do to accomplish this?
EDIT
Thanks to Scopey I've worked out a while loop, but it's not functioning correctly. Here is what I have:
$startTimes = array_column($startTimes, 'time');
$endTimes = array_column($endTimes, 'time');
while (($startTime = current($startTimes)) !== false && ($endTime = current($endTimes) !== false)) {
$startTimesConv = strtotime($startTimes);
$endTimesConv = strtotime($endTimes);
$totalTime = ($startTimesConv - $endTimesConv)/60/60;
next($startTimes);
next($endTimes);
}
If you want to loop two arrays at the same time, you can use the PHP functions for traversing arrays by manipulating their internal pointer: current, next, reset, end and prev.
You just need to make a while loop:
while (($startTime = current($startTimes)) !== false && ($endTime = current($endTimes) !== false) {
// ... Do things
next($startTimes);
next($endTimes);
}
See the documentation for next and current
To iterate two regular arrays with the same length use for instead of foreach:
$length = count($start_times);
for ($i = 0; $i < $length; $i++) {
$start_time = $start_times[$i]["time"];
$stop_time = $stop_times[$i]["time"];
// do things
}
But in your case, I strongly recommend that calculate the differences in SQL.
I would take a step back and look at the queries themselves. You are trying to do a calculation between two times which are related in your database however, the relationship gets lost by separating the times into two separate arrays. Or at the very least is ambiguously related as an array index.
My pseudocode would look like this:
#For each ticket which is closed
#Get an array (time entries) of arrays (start, stop) (each having it's start and stop time)
#total_time = 0
#For each time entry
#Perform a time calc function to get_time_differnce(start, stop)
#Add the time to Total_time
#Add total_time to ticket record in DB
If you showed some more detail I might be able to expand. (i.e The queries themselves)

Check for all combinations of key values in array?

I have this dataset to work with:
Array
(
[John Doe] => Array
(
[137] => 7
[22] => 8
[145] => 7
)
[George] => Array
(
[143] => 2
[18] => 7
)
[Alisa Baumbach] => Array
(
[148] => 7
[145] => 5
)
)
Now I want to see if I have atleast one match between the user arrays between on their keys. I would do this by using array_intersect_key:
$matches = array_intersect_key($user_cor['John Doe'], $user_cor['Alisa Baumbach']);
This works ofcourse but these values are hardcoded, I want to automate this to run all combinations through it. How would I go about checking if:
User 1 data intersects with User 2
User 2 data intersects with User 3
User 1 data intersects with User 3
Ofcourse this is already minified to 3 comparisons instead of 6 since I removed the doubles because I only want unique combinations. How would I go about doing this?
I know this seems fairly typical and all but I have a lot of difficulty with phrasing this let alone searching for answers on how to do this.
Your time would be greatly appreciated in helping me understand this problem.
Something like the following?
$keys = array_keys($user_cor);
for ($i = 0;$i < count($keys);$i++) {
for ($j = $i+1;$j < count($keys);$j++) {
$matches[$i.",".$j] = array_intersect_key($user_cor[$keys[$i]], $user_cor[$keys[$j]])
}
}

If value exists in one PHP array, add value to second array

I have two PHP arrays. One contains a group name and another contains a pay wage value.
$group_wages_array = Array ( [0] => 1 [1] => 4 [2] => 1 [3] => 3 );
This means there are four employees on the schedule. Two are assigned to group 1, another to group 4 and the last to group 3.
The second array is as follows:
$tot_wages_array = Array ( [0] => 500 [1] => 44 [2] => 80 [3] => 11.25 );
This is a sample array of each employee's wage. Both arrays are constructed in order as values are added in a mysql while loop as it pulls the info from the database.
Later on down the line, I combine the two arrays to get one array where the key is the group number and the value is the total wages for that group:
$combined_group_wages = array_combine($group_wages_array, $tot_wages_array);
This works like a charm EXCEPT for when more than one employee is assigned to the same group. These arrays are built in a mysql while loop as it loops through each employee's info:
array_push($tot_wages_array, $totemp_wages_sch); // Add their wage to the array
array_push($group_wages_array, $emp_data['group_id']); // Add their group to the array
Instead of just pushing the data to the array, I need to do this... I know the english but I don't know how to code it:
If $emp_data['group_id'] exists as value in $group_wages_array, add nothing to this array but get the key. Add $totemp_wages_sch to $tot_wages_array where key = group_wages_array key
I know it sounds more like an SQL query but I have to keep the keys and values in order so that they can be combined later in the page. If I can get this to work right, The arrays shown in the example would be:
$group_wages_array = Array ( [0] => 1 [1] => 4 [2] => 3 );
$tot_wages_array = Array ( [0] => 580 [1] => 44 [2] => 11.25 );
$combined_group_wages = array_combine($group_wages_array, $tot_wages_array);
$combined_group_wages = Array ( [1] => 580 [4] => 44 [3] => 11.25 );
...I've got to make this work using PHP. Any ideas?
I came up with a solution based on a combination of two of the answers submitted below. Here it is if it can help someone:
if(in_array($emp_data['group_id'], $group_wages_array)){
$key = key($group_wages_array);
$tot_wages_array[$key] += $totemp_wages_sch;
} else {
array_push($group_wages_array, $emp_data['group_id']);
array_push($tot_wages_array, $totemp_wages_sch);
}
This should do it:
$group_wages_array = array(1, 4, 1, 3);
$tot_wages_array = array(500, 44, 80, 11.25);
$combined_group_wages = array();
for ($i=0; $i<count($group_wages_array); $i++) {
$group = $group_wages_array[$i];
if (array_key_exists($group_wages_array[$group], $combined_group_wages)) {
$combined_group_wages[$group] += $tot_wages_array[$i];
} else {
$combined_group_wages[$group] = $tot_wages_array[$i];
}
}
print_r($combined_group_wages);
Yields:
Array
(
[1] => 580
[4] => 44
[3] => 11.25
)
But I recommend that you just switch to using objects to better represent your data.
If I could see the entirety of the code that would help a lot, but here's your English converted to php. Show me more code and I can perfect it, until then try this ->
if(in_array($emp_data['group_id'], $group_wages_array)){
$key = key($group_wages_array);
$tot_wages_array[$key] = $totemp_wages_sch;
} else {
array_push($group_wages_array, $emp_data['group_id']);
}

Categories