Find sum of calls data from array using another array of dates - php

$array1 = Array (
[0] => Array
(
[day] => 2014-05-07
[total_Calls] => 1
)
[1] => Array
(
[day] => 2014-05-09
[total_Calls] => 1
)
[2] => Array
(
[day] => 2014-05-12
[total_Calls] => 1
)
[3] => Array
(
[day] => 2014-05-13
[total_Calls] => 1
)
[4] => Array
(
[day] => 2014-05-14
[total_Calls] => 2
)
[5] => Array
(
[day] => 2014-05-16
[total_Calls] => 4
)
);
$array2 = Array (
[0] => Array
(
[report_date] => 1397413800-1397932200
)
[1] => Array
(
[report_date] => 1398018600-1398537000
)
[2] => Array
(
[report_date] => 1398623400-1399141800
)
[3] => Array
(
[report_date] => 1399228200-1399746600
)
[4] => Array
(
[report_date] => 1399833000-1400351400
)
[5] => Array
(
[report_date] => 1400437800-1400956200
)
)
I want to find sum of total_Calls between dates that is in second array. I need out put like this.
I have got output using for loop but i dont want to use for loop
$array = array();
foreach ($array1 as $val) {
$temp = str_replace('-', '', $val['day']);
$array[strtotime($temp)] = $val['total_Calls'];
}
$week = array();
$sum = array();
foreach ($array as $k => $v) {
foreach ($array2 as $val) {
$temp = explode('-', $val['report_date']);
if ($k >= $temp[0] && $k <= $temp[1]) {
$sum[$val['report_date']][] = $v;
} else {
$sum[$val['report_date']][] = 0;
}
}
}
Output:
[1397413800-1397932200] => 0
[1398018600-1398537000] => 0
[1398623400-1399141800] => 0
[1399228200-1399746600] => 2
[1399833000-1400351400] => 9
[1400437800-1400956200] => 8

BRUTEFORCE!!!
<?php
$from_to = array();
foreach ($array2 as $data) {
$days = explode('-', $data['report_date']);
$from_to[] = $days;
}
$counter = array();
foreach ($array1 as $data) {
$day = new Datetime($data['day'], new Datetimezone('UTC'));
$timestamp = $day->('U');
foreach ($from_to as $range) {
if ($timestamp >= $range[0] && $timestamp <= $range[1]) {
$key = implode('-', $range);
if (!isset($counter[$key])) {
$counter[$key] = 0;
}
$counter[$key] += $data['total_Calls'];
}
}
}
print_r($counter);

There is no point in trying to avoid using loops. In fact, however you do it, you will be using loops. Either by writing one, or by using some native or custom function that will eventually use one. As that is just the way you walk through an array.
What you might want to do however is try to have as little loops as possible. And do the heavy work, such as strtotime() outside (most of) the loops, where possible.
I've given your code a walk over and compacted it. You will have your results inside $new_array.
foreach($array1 as $key=>$value)
$array1[$key]["timestamp"] = strtotime($array1[$key]["day"]);
foreach($array2 as $report) {
$new_array[$report["report_date"]] = 0;
$from_to = array_map("intval",explode("-",$report["report_date"]));
foreach($array1 as $call_day) {
$day = $call_day["timestamp"];
if ($day >= $from_to[0] && $day < $from_to[1])
$new_array[$report["report_date"]] += $call_day["total_Calls"];
}
}
DEMO

Related

Simplify Array Duplicate Element in Array PHP

How can we find the count of duplicate elements in a multidimensional array,
I have an array like this:
Array
(
[0] => Array
(
[brti] => 29
)
[1] => Array
(
[voda] => 6
)
[2] => Array
(
[btel] => 8
)
[3] => Array
(
[btel] => 10
)
)
Question: How to simplify the structure of array, i mean can be counting the value if there is indicate that have same key ?
just like this:
Array
(
[0] => Array
(
[brti] => 29
)
[1] => Array
(
[voda] => 6
)
[2] => Array
(
[btel] => 18
)
)
So far, i've tried this way, but it didn't help me. My array is store in $test
$test = [sample array]
$count = array();
foreach ($test as $key => $value) {
foreach ($value as $k => $val) {
if (isset($count[$val])) {
++$count[$val];
} else {
$count[$value] = 1;
}
}
}
print_r($count);
<?php
$array = [
"0" => ["brti" => 29],
"1" => ["voda" => 6],
"2" => ["btel" => 8],
"3" => ["btel" => 10],
];
$final = array();
array_walk_recursive($array, function($item, $key) use (&$final){
$final[$key] = isset($final[$key]) ? $item + $final[$key] : $item;
});
print_r($final);
});
check demo
You can do it in very simple way,
$test = [];
foreach ($array as $value)
{
foreach ($value as $k => $v)
{
// $test[$k] = ($test[$k] ?? 0); // initialised if not php 7+
$test[$k] = (empty($test[$k]) ? 0: $test[$k]); // below php 7
$test[$k] += $v;
}
}
print_r($test);
Output:
Array
(
[brti] => 29
[voda] => 6
[btel] => 18
)
Working demo.

How to group keys and values of an (sub)array and sum its values using PHP? [duplicate]

This question already has answers here:
Group array data on one column and sum data from another column
(5 answers)
Closed 9 months ago.
I have the following array
Array (
[0] => Array
(
[0] => ALFA
[1] => 213
)
[1] => Array
(
[0] => ALFA
[1] => 151
)
[2] => Array
(
[0] => ALFA
[1] => 197
)
[3] => Array
(
[0] => BETA
[1] => 167
)
[4] => Array
(
[0] => ZETA
[1] => 254
)
[5] => Array
(
[0] => GAMA
[1] => 138
)
[6] => Array
(
[0] => GAMA
[1] => 213
)
)
And I would like to group the key[0] of the subarray so I can see how many equal keys it has.
Something like that:
ALFA => 3
BETA => 1
EPSI => 1
GAMA => 2
I tried with array_count_values, but without success.
foreach ($array as $value) {
echo '<pre>';
print_r(array_count_values($value));
echo '</pre>';
}
With that we have following result:
Array
(
[ALFA] => 1
[213] => 1
)
Array
(
[ALFA] => 1
[151] => 1
)
...
Array
(
[GAMA] => 1
[213] => 1
)
And after that I would like to sum the values of each group as well.
ALFA => 213 + 151 + 197
BETA => 167
ZETA => 254
GAMA => 138 + 213
I think that when we solve the first part of the problem, the second would follow easier with quite the same method.
The final purpose is to divide the sum of values by the number of occurrences of each key group, so we can have an average of the values just like that:
ALFA => (213+151+197) / 3 = 187
BETA => 167
ZETA => 254
GAMA => (138+213) / 2 = 175,5
This is not the main problem, but as I said, I'm stuck with the beginning of the solution and would appreciate any help.
I'm surprised at all the long and complicated answers. However, the initial foreach to model your data to something manageable is needed. After that you just need to do a really simple array_walk.
<?php
$result = array();
foreach ($array as $el) {
if (!array_key_exists($el[0], $result)) {
$result[$el[0]] = array();
}
$result[$el[0]][] = $el[1];
}
array_walk($result, create_function('&$v,$k', '$v = array_sum($v) / count($v);'));
?>
Result:
Array
(
[ALFA] => 187
[BETA] => 167
[ZETA] => 254
[GAMA] => 175.5
)
Solution for you is here:
Code:
$input = [
['alfa', 123],
['alfa', 223],
['alfa', 122],
['alfa', 554],
['alfa', 34],
['dalfa', 123],
['halfa', 223],
['dalfa', 122],
['halfa', 554],
['ralfa', 34]
];
$result = [];
foreach ($input as $node) {
if (isset($result[$node[0]])) {
$result[$node[0]] = ['sum' => $result[$node[0]]['sum'] + $node[1], 'count' => $result[$node[0]]['count'] + 1];
} else {
$result[$node[0]] = ['sum' => $node[1], 'count' => 1];
}
}
print_r($result);
foreach ($result as $key => &$data) {
$data = $data['sum'] / $data['count'];
}
print_r($result);
Output:
Array
(
[alfa] => Array
(
[sum] => 1056
[count] => 5
)
[dalfa] => Array
(
[sum] => 245
[count] => 2
)
[halfa] => Array
(
[sum] => 777
[count] => 2
)
[ralfa] => Array
(
[sum] => 34
[count] => 1
)
)
Array
(
[alfa] => 211.2
[dalfa] => 122.5
[halfa] => 388.5
[ralfa] => 34
)
$sort = array();
foreach ($array as $value) {
$sort[$value[0]][] = $value[1];
}
then you count how many keys each has
$keys = array();
foreach($sort as $k => $v) {
$keys[$k] = count($v);
}
then for calculating the amount
$sum = array();
$average = array();
foreach($sort as $k => $v) {
$amount = 0;
foreach($v as $val) {
$amount += $val;
}
$sum[$k] = $amount;
$average[$k] = $amount / $keys[$k];
}
HOWEVER, If you want all the details in one array:
$final = array();
foreach ($array as $value) {
$final[$value[0]]["values"][] = $value[1];
}
foreach($final as $k => $v) {
$final[$k]["amount"] = count($v['values']);
$amount = 0;
foreach($v['values'] as $val) {
$amount += $val;
}
$final[$k]["sum"] = $amount;
$final[$k]["average"] = $amount / $final[$k]["amount"];
}
example: http://jdl-enterprises.co.uk/sof/25789697.php
Includes Output
Just copy the codes to your favorite text editor, sure it works perfectly.
$items = [
['ALFA',213],
['ALFA',151],
['ALFA',197],
['BETA',167],
['ZETA',254],
['GAMA',138],
['GAMA',213]
];
echo '<pre>' . print_r($items,true) . '</pre>';
$result;
foreach ($items as $value) {
# code...
if (isset($result[$value[0]])) {
$sum = $result[$value[0]]['sum'] + $value[1];
$count = $result[$value[0]]['count'] + 1;
$result[$value[0]] = ['sum' => $sum , 'count' => $count, 'divided' => ($sum / $count)];
} else {
$result[$value[0]] = ['sum' => $value[1] , 'count' => 1 , 'divided' => ($value[1] / 1) ];
}
}
echo '<pre>' . print_r($result,true) . '</pre>';
$myArray = [
["ALFA",213],
["ALFA",151],
["ALFA",197],
["BETA",167],
["ZETA",254],
["GAMA",138],
["GAMA",213]
];
$a1 = array(); //TEMPORARY ARRAY FOR KEEPING COUNT & TOTAL VALUES
$res = array(); //ARRAY USED TO KEEP RESULT
foreach($myArray as $val)
{
//AVOID PESKY NOTICES FOR UNDEFINED INDEXES
if ( !array_key_exists($val[0],$a1) ) {
$a1[$val[0]] = array("count" => 0,"total" => 0);
$res[$val[0]] = 0;
}
//INCREMENT THE COUNT OF INSTANCES OF THIS KEY
$a1[$val[0]]["count"]++;
//INCREMENT THE TOTAL VALUE OF INSTANCES OF THIS KEY
$a1[$val[0]]["total"]+=$val[1];
// UPDATE RESULT ARRAY
$res[$val[0]] = $a1[$val[0]]["total"] / $a1[$val[0]]["count"];
}
print_r($res);
Should result in:
Array
(
[ALFA] => 187
[BETA] => 167
[ZETA] => 254
[GAMA] => 175.5
)
Sample: http://phpfiddle.org/lite/code/a7nt-5svf

How to merge two array in according to value in PHP?

I have two array and I need to merge it together !!
Array 1
Array
(
[0] => Array
(
[brand] => CARTIER
[amount_2014] => 136476
)
[1] => Array
(
[brand] => TIFFANY & CO.
[amount_2014] => 22000
)
[2] => Array
(
[brand] => Test
[amount_2014] => 33000
)
)
Array 2
Array
(
[0] => Array
(
[brand] => CARTIER
[amount_2013] => 22052
)
[1] => Array
(
[brand] => Test
[amount_2013] => 3313
)
)
I need the result array as:
Array
(
[0] => Array
(
[brand] => CARTIER
[amount_2014] => 136476
[amount_2013] => 22052
)
[1] => Array
(
[brand] => TIFFANY & CO.
[amount_2014] => 22000
[amount_2013] => 0
)
[2] => Array
(
[brand] => Test
[amount_2014] => 33000
[amount_2013] => 3313
)
)
So for every [brand] I need the amount in [amount_2014] & [amount_2013], if any one is not present then I need it value as 0;
I am using CodeIgniter for this project, I have only one table with field (brand, amount, year) am issuing two queries for getting sum of amount for 2013 & 2014.
(I am fighting with array_merge and array_combine but no use for me in this case, if any one can help with query then it's also very much helpful).
Try this:
function cars_array_merge()
{
$arrays = func_get_args();
foreach ($arrays as &$array)
{
$new_arr = array();
foreach ($array as $value)
{
$brand = $value['brand'];
unset($value['brand']);
$new_arr[$brand] = $value;
}
$array = $new_arr;
}
$arrays = call_user_func_array('array_merge_recursive', $arrays);
foreach ($arrays as $brand => &$array)
$array['brand'] = $brand;
return array_values($arrays);
}
// testing
$arr1 = [
[ 'brand' => 'CARTIER', 'mount_2014' => 136476 ],
[ 'brand' => 'TIFFANY & CO.', 'mount_2014' => 22000 ]
];
$arr2 = [
[ 'brand' => 'CARTIER', 'mount_2013' => 22052 ]
];
print_r(cars_array_merge($arr1, $arr2));
Output:
Array
(
[0] => Array
(
[mount_2014] => 136476
[mount_2013] => 22052
[brand] => CARTIER
)
[1] => Array
(
[mount_2014] => 22000
[brand] => TIFFANY & CO.
)
)
<?php
for ($i = 0, $max = count($arr1); $i < $max; ++$i) {
$arr1[$i]['amount_2013'] = isset($arr2[$i]['amount_2013']) ? $arr2[$i]['amount_2013'] : 0;
}
$merge = array_merge($arr1, $arr2);
$temp = $merge;
$newArr = array(); $key_array = array();
foreach($merge as $key=>$val){
$b = $val['brand'];
$a1 = isset($val['amount_2013']) ? $val['amount_2013'] : 0;
$a2 = isset($val['amount_2014']) ? $val['amount_2014'] : 0;
unset($temp[$key]);
foreach($temp as $k=>$values){
if($values['brand'] == $b){
if($a1 == 0){
$a1 = isset($values['amount_2013']) ? $values['amount_2013'] : 0;
}
if($a2 == 0){
$a2 = isset($values['amount_2014']) ? $values['amount_2014'] : 0;
}
unset($temp[$k]);
}
}
if(!in_array($b, $key_array))
{
$newArr[] = array('brand' => $b, 'amount_2014' => $a2, 'amount_2013' => $a1);
}
$key_array[] = $b;
}
print_r($newArr);
This is what I used:
<?php
$arr1 = array(0=>array("brand"=>"CARTIER","amount_2014"=>136476), 1=>array("brand"=>"tiffany","amount_2014"=>22000));
$arr2 = array(0=>array("brand"=>"CARTIER","amount_2013"=>22000));
foreach ($arr2 as $key=>$value){
if( $value["brand"] == "CARTIER")
{
$arr1[0]["amount_2013"] = $value["amount_2013"];
$arr1[1]["amount_2013"] = 0;
}
else
{
$arr1[1]["amount_2013"] = $value["amount_2013"];
$arr1[0]["amount_2013"] = 0;
}
}
print_r($arr1);
?>

php sum of array

I have the following array with multiple levels. I wish to get the sum total of [price], [adults] and [childern] but have not been able traverse the levels.
The answer I should get with this example is price=380 adults=5 and children=1
Array (
[8] => Array (
[2] => Array (
[num_rooms] => 2
[adults] => Array (
[0] => 1
[1] => 1
)
[children] => Array (
[0] => 0
[1] => 0
)
[prices] => Array (
[0] => 50
[1] => 50
)
[price] => 130
[supp] => 30
)
[3] => Array (
[num_rooms] => 1
[adults] => Array (
[0] => 1
)
[prices] => Array (
[0] => 100
)
[price] => 150
[supp] => 50
)
)
[1] => Array (
[2] => Array (
[num_rooms] => 2
[adults] => Array (
[0] => 1
[1] => 1
)
[children] => Array (
[0] => 1
[1] => 0
)
[prices] => Array (
[0] => 75
[1] => 75
)
[price] => 170
[supp] => 20
)
)
)
Thanks
Two loops and a helper array:
$sums = array ( 'price' => 0, 'adults' => 0, 'children' => 0 );
foreach($array as $outer) {
foreach($outer as $inner) {
$sums['price'] += $inner['price'];
$sums['adults'] += array_sum($inner['adults']);
$sums['children'] += array_sum($inner['children']);
}
}
print_r($sums);
With a more dynamic version of the inner loop:
foreach($array as $outer) {
foreach($outer as $inner) {
foreach($sums as $key => &$v)
$v += is_array($inner[$key])
? array_sum($inner[$key])
: $inner[$key];
}
}
This should work:
$price = 0;
$adults = 0;
$children = 0;
foreach($arr as $l1_key => $l1_value) // iterates over the first level array
{
foreach($l1_value as $l2_key => $l2_value) // iterates over second level arrays
{
$price += $l2_value['price']; // add up price totals
foreach($l2_value['adults'] as $value) // iterate through adults array values
{
$adults += $value; // sum up adult count
}
foreach($l2_value['children'] as $value) // iterate through children array values
{
$children += $value; // sum up children count
}
}
}
// now $price, $adults, and $children contain the totals for each
I didn't test this code but at the same time I don't know how you got 380.. I'm seeing 350?
$sums = getSum($arr);
print_r($sums);
function getSum($arr) {
$sums = array();
$sums2 = array();
$sums['adults'] = 0;
$sums2['adults'] = 0;
$sums['children'] = 0;
$sums2['children'] = 0;
$sums['prices'] = 0;
$sums2['prices'] = 0;
foreach ($arr as $key => $value) {
$do_not_recurse = false;
switch ($key) {
case 'adults':
$do_not_recurse = true;
foreach ($value as $adults)
$sums['adults'] += $adults;
break;
case 'children':
$do_not_recurse = true;
foreach ($value as $children)
$sums['children'] += $children;
break;
case 'prices':
$do_not_recurse = true;
foreach ($value as $price)
$sums['prices'] += $price;
break;
default:
break;
}
if (is_array($value))
$sums2 = getSum($value);
}
$sums['adults'] += $sums2['adults'];
$sums['children'] += $sums2['children'];
$sums['prices'] += $sums2['prices'];
return $sums;
}
Handles any depth or array structure and just picks out the terms with the names you are looking for:
function find($term, $array) {
$count = 0;
foreach ($array as $item)
if (is_array($item)) $count += find($term, $item);
if (isset($array[$term]) {
if (is_array($array[$term])) $count += array_sum($array[$term]);
else $count += $array[$term];
}
return $count;
}
echo count('price', <the array>);
echo count('adults', <the array>);
echo count('children', <the array>);

Comparing multiple different dates and getting the average in PHP

I use a function called count_days($date1,$date2) that counts the number of days between two dates. But, my question is: the dates come from the DB, in an array like:
Array (
[imac] => Array (
[0] => 2002-10-10
[1] => 2003-11-22
[3] => 2004-11-10
)
[iphone] => Array (
[0] => 2007-09-11
[1] => 2008-05-12
[2] => 2009-06-14
[3] => 2010-06-05
)
)
As you can see the products may have a different number of subarrays. I want to count the days between the first and the next date (and so on!) and then get the average of days.
The DateInterval class is great for this kind of date arithmetic. You can use DateTime::add, DateTime::subtract and DateTime::diff to work with them.
<?php
$types = array(
'imac' => array ('2002-10-10', '2003-11-22', '2004-11-10'),
'iphone' => array ( '2007-09-11', '2008-05-12', '2009-06-14', '2010-06-05'),
);
$typeIntervals = array();
$typeAverage = array();
foreach ($types as $type=>$dates) {
$last = null;
$typeIntervals[$type] = array();
foreach ($dates as $date) {
$current = new DateTime($date);
if ($last) {
$interval = $current->diff($last);
$typeIntervals[$type][] = $interval->days;
}
$last = $current;
}
$typeAverage[$type] = array_sum($typeIntervals[$type]) / count($typeIntervals[$type]);
}
print_r(typeIntervals);
print_r($typeAverage);
This will output:
Array (
[imac] => Array (
[0] => 408
[1] => 354
)
[iphone] => Array (
[0] => 244
[1] => 398
[2] => 356
)
)
Array (
[imac] => 381
[iphone] => 332.66666666667
)
try smth like this ( not tested )
$lastDate = $dbArray[0][0];
$daysArray = array();
foreach ( $dbArray as $value )
{
if ( is_array($value) )
{
foreach ( $value as $v )
{
$daysArray[] = count_days($lastDate, $v);
$lastDate = $v;
}
} else {
//not an array check if it's a date and test it here
}
}
$average = array_sum($daysArray)/count($daysArray);

Categories