I want to calculate the totals for a series of columns in a table, how do I go about doing this?
Here is a sample of the data I want to sum:
array:1 [
"traders" => array:6 [
"Jim Mayor__targeted_target" => array:2 [
"amounts" => array:13 [
0 => 5
1 => 5
2 => 0
3 => 0
4 => 0
5 => 0
6 => 0
7 => 0
8 => 0
9 => 0
10 => 0
11 => 0
]
"row_name" => "Targeted target"
]
"Jim Mayor__actual_targeted" => array:2 [
"amounts" => array:13 [
0 => 0
1 => 1
2 => 0
3 => 0
4 => 0
5 => 0
6 => 1
7 => 1
8 => 0
9 => 0
10 => 0
11 => 0
]
"row_name" => "Actual targeted"
]
"Bob Martinez__targeted_target" => array:2 [
"amounts" => array:13 [
0 => 1
1 => 0
2 => 0
3 => 0
4 => 0
5 => 0
6 => 0
7 => 0
8 => 0
9 => 0
10 => 0
11 => 0
]
"row_name" => "Targeted target"
]
"Bob Martinez__actual_targeted" => array:2 [
"amounts" => array:13 [
0 => 19
1 => 45
2 => 20
3 => 26
4 => 21
5 => 10
6 => 12
7 => 20
8 => 11
9 => 2
10 => 0
11 => 0
]
"row_name" => "Actual targeted"
]
...
I want to sum together each index, e.g. for Jim Mayor__targeted_target, index 0 added to index 0 of Bob Martinez__targeted_target (this gives the total for January). It needs to work with an unlimited number of traders.
The function that generates the data:
protected function addRow($func, $params, $data, $year, $traderName, $rowName, $type, $image = null, $format = null, $underline = false)
{
$date = Carbon::createFromDate($year, 4, 1);
$total = 0;
$traderName = $traderName . '__' . str_replace(' ', '_', strtolower($rowName));
for ($i = 1; $i < 13; $i++) {
$params[1] = $date->year;
$params[2] = $date->month;
$result = call_user_func_array($func, $params);
$data['traders'][$traderName]['amounts'][] = $result ? $result : 0;
$total += $result;
$date->addMonth();
}
$data['traders'][$traderName]['amounts'][] = $total;
$data['traders'][$traderName]['row_name'] = $rowName;
return $data;
}
Just go over your data and save results in an additional array:
$results = array();
foreach ($traders as $trader) {
foreach ($trader['amounts'] as $i => $amount) {
if (!isset($results[$i])) {
$results[$i] = 0;
}
$results[$i] += $amount;
}
}
The result array will contains the sums of all traders.
Not tested but should work.
Do something like this:
function sumRowsByMonth($traders)
{
$sums = array_fill(0, 12, 0);
foreach($traders as $trader) {
foreach($trader['amounts'] as $monthId => $amount) {
$sums[$monthId] += $amount;
}
}
return $sums;
}
I tested with this:
$arr = array(
'traders' => array(
'Jim Mayor__targeted_target' => array(
'amounts' => array(
0 => 5,
1 => 5,
2 => 0,
3 => 0,
4 => 0,
5 => 0,
6 => 0,
7 => 0,
8 => 0,
9 => 0,
10 => 0,
11 => 0,
)
),
'Bob Martinez__targeted_target' => array(
'amounts' => array(
0 => 19,
1 => 45,
2 => 20,
3 => 26,
4 => 21,
5 => 10,
6 => 12,
7 => 20,
8 => 11,
9 => 2,
10 => 0,
11 => 0,
)
),
),
);
var_dump(sumRowsByMonth($arr['traders']));
Use array_sum() function.
array_sum() returns the sum of values in an array
Also, you said you want to count targeted target and actual targeted separately.
$actual = [];
$targeted = [];
foreach ($traders as $trader) {
$sum = array_sum($trader['anmounts']);
$trader['row_name'] === 'Actual targeted') ? $actual += $sum : $target += $sum;
}
Maybe you'll need to modify this a little bit to tune behavior, but I guess I got the idea.
#imperium2335:
The main problem I keep getting that it is summing all rows, including actual_targeted. actual_targeted needs to be grouped and summed separately to targeted_target.
Then do this:
function sumRowsByMonth($traders)
{
$sums = array();
foreach($traders as $traderName => $trader) {
$type = strstr($traderName, '__');
if( empty($sums[$type]) ) {
$sums[$type] = array_fill(0, 12, 0);
}
foreach($trader['amounts'] as $monthId => $amount) {
$sums[$type][$monthId] += $amount;
}
}
return $sums;
}
Read this:
http://php.net/manual/en/function.strstr.php
Related
this questin is asked many times but every one using same array but in my case i have 2 arrays
consider i have 2 arrays
array1:3 [
10 => 900.0
20 => 450.0
30 => 600.0
]
array2:3 [
30 => 200.0
10 => 500.0
20 => 600.0
]
output should be
[900.0 - 500 = 400 // according to same id 10 = 10
450.0 - 600 = -150 // 20 = 20
600.0 - 200 = 400 // 30 = 30
]
in this array consider 10,20,30 are ids and next is value i want output where compare ever id and get difference example if (id1 = id2 ){ id1 => value - id2 => value }
i need help in that code which i already tried
$getsellerreport = SellerSellsReport::where('seller_id' , $seller_id);
$getunitdiff = $getsellerreport->pluck('unit')->toArray();// [0 => 75 1 => 500 => 100]
$getamountdiff = $getsellerreport->pluck('amount')->toArray(); // [0 => 11000 => 40 2 => 900]
$getproductdiff = $getsellerreport->pluck('product_id')->toArray(); // [0 => 39 1 => 242 => 23]
foreach($product_report as $preport){
$unit[] = $preport['unit'];// [0 => 75 1 => 25 2 => 100]
$amount[] = $preport['amount'];// [0 => 900 1 => 450 2 => 600]
$product_id[] = $preport['product_id'];// [0 => 23 1 => 242 => 39]
} // here we get array two values
above code get values with starting 0 key value and on below for() loop we can use product_id to compare both product id and get unit and amount but i dont know how i can do that can someone help me?
for ($i = 0 ; $i < sizeof($amount) ; $i++){
$unitdiff[] = $getunitdiff[$i] - $unit[$i];
$amountdiff[] = $getamountdiff[$i] - $amount[$i];
}
You could collect the arrays and use map, here is a sample to get you started:
$a = [
10 => 900.0,
20 => 450.0,
30 => 600.0,
];
$b = [
30 => 200.0,
10 => 500.0,
20 => 600.0,
];
$x = collect($a)->map(function($aItem, $index) use ($b) {
return $aItem - $b[$index];
});
dd($x); // yields [ 10 => 400.0, 20 => -150.0, 30 => 400.0 ]
My array is
$array = [
1 => 0
2 => 0
3 => 0
4 => 0
5 => 0
6 => 0
7 => 2
8 => 0
9 => 0
10 => 1
11 => 0
12 => 1
];
As a result i want it to be
$array = [
10 => 1
11 => 0
12 => 1
1 => 0
2 => 0
3 => 0
4 => 0
5 => 0
6 => 0
7 => 2
8 => 0
9 => 0
];
And my logic for now is
$sorted = collect($array)
->sortBy(function ($count, $month) {
return $month <= 9;
});
But the result is not what I expected :(
Basically i want last index to be current month and so on back.
Please help me!
You can do it like this:
$sorted = collect($array)->sortBy(function ($count, $month) {
$currentMonth = (int) \Carbon\Carbon::now()->month;
return ($month + (12 - $currentMonth - 1)) % 12;
});
You can function form php that
krsort();
krsort can sort associative arrays in descending order, according to the key. So
ksort($array);
I have a dynamic multidimensional array like this:
$myarray = array(
array(
0 => 0,
1 => 70,
2 => 19,
3 => 0
),
array(
0 => 0,
1 => 24,
2 => 14
),
array(
0 => 0,
1 => 15,
2 => 11,
3 => 0
),
array(
0 => 0,
1 => 15,
2 => 27,
3 => 0
)
);
I need to loop through the subarrays and overwrite the current values of each subarray to represent the difference between the original value and the following value with respect to the subarray keys.
This describes the arithmetic desired on each subarray element (the value after the = is the new desired value):
$myarray = array(
array(
0 => 0 - 0 = 0
1 => 70 - 24 = 46
2 => 19 - 30 = -11
3 => 0 - 0 = 0
),
array(
0 => 0 - 0 = 0
1 => 24 - 0 = 24
2 => 14 -(-16) = 30
3 => 0 - 0 = 0
),
array(
0 => 0 - 0 = 0
1 => 15 - 15 = 0
2 => 11 - 27 = -16
3 => 0 - 0 = 0
),
array(
0 => 0,
1 => 15,
2 => 27,
3 => 0
)
);
I tried to do something, but it is not what I need and it contains errors:
$new_array = array();
foreach($myarray as $key => $values) {
foreach($values as $k_key => $v_values) {
$calc = $values[$k_key+1]-$v_values;
array_push($new_array , $calc);
}
}
var_dump($new_array);
Start from 2nd last subarray, and loop toward the start
Find the longer array's length of the two targeted arrays
Iterate and perform subtractions / declarations
declare/overwrite new values as they are encountered
Code: (Demo)
$myarray = [
[0, 70, 19, 0],
[0, 24, 14], // note missing 4th element
[0, 15, 11, 0],
[0, 15, 27, 0]
];
for ($i = count($myarray) - 2; $i >= 0; --$i) {
$max = max(count($myarray[$i]), count($myarray[$i+1]));
for($k = 0; $k < $max; ++$k) {
$myarray[$i][$k] = ($myarray[$i][$k] ?? 0) - ($myarray[$i+1][$k] ?? 0);
}
}
var_export($myarray);
I have a multidimensional array $elements where I need to fill it with values from the array $ratings. The array $ratings is built so the first value will fit into the first slot in elements, the next in the second and so on.
$elements
4 => array:3 [▼
2 => 0
3 => 0
4 => 0
]
5 => array:3 [▼
2 => 0
3 => 0
4 => 0
]
7 => array:3 [▼
2 => 0
3 => 0
4 => 0
]
I now need to fill $elements with 9 specific values from
$ratings
array:9 [▼
0 => 3
1 => 2
2 => 1
3 => 3
4 => 3
5 => 2
6 => 3
7 => 2
8 => 1
9 => 3
]
If I manage to loop through $elements, inserting values from $ratings one by one, I will have solved my problem.
So $elements[4][2] should have the value of 3, $elements[4][3] should have value of 2 etc.
Also you can manipulate these by array_fill using loop.
Try this:
<?php
$elements = [
4=>[2=>0, 3=>0, 4=>0],
5=>[2=>0, 3=>0, 4=>0],
7=>[2=>0, 3=>0, 4=>0],
];
$ratings = [ 0 => 3, 1 => 2, 2 => 1, 3 => 3, 4 => 3, 5 => 2, 6 => 3, 7 => 2, 8 => 1, 9 => 3 ];
$ratingsIndex = 0;
foreach(array_keys($elements) as $ElementsIndex) {
foreach(array_keys($elements[$ElementsIndex]) as $ElementsSubIndex) {
$elements[$ElementsIndex][$ElementsSubIndex] = $ratings[$ratingsIndex++];
}
}
echo "<pre>";
print_r($elements);
echo "</pre>";
?>
Say I have an array with keys representing id and values representing parent:
4 => 0
2 => 0
5 => 2
6 => 5
8 => 0
9 => 0
10 => 8
12 => 0
13 => 0
14 => 0
18 => 7
19 => 18
20 => 19
21 => 20
22 => 21
23 => 22
24 => 23
28 => 20
7 => 5
You could also read this as an object:
{
id : 4,
parent : 0
} // etc...
The multidimensional array I'd want to achieve from this would be:
4 => 0
2 => 5
=> 6
=> 7
=> 18
=> 19
=> 20
=> 21
=> 22
=> 23
=> 24
=> 28
8 => 10
9 => 0
12 => 0
13 => 0
14 => 0
How would I go about doing this?
If you write a little helper function to rework your data to a structure similar to:
$input = array(
array('id' => '4', 'parent' => '0'),
// ...
);
which could be achieved with something like:
$data = array_map(function ($entry) {
list($id, $parent) = array_map('trim', explode('=>', $entry));
return array(
'id' => $id,
'parent' => $parent
);
}, explode("\n", $data));
you could then use a function I used in a similar question:
function flatToNested($d, $r = 0, $p = 'parent', $k = 'id', $c = 'children') {
$m = array();
foreach ($d as $e) {
isset($m[$e[$p]]) ?: $m[$e[$p]] = array();
isset($m[$e[$k]]) ?: $m[$e[$k]] = array();
$m[$e[$p]][] = array_merge($e, array($c => &$m[$e[$k]]));
}
return $m[$r];
}
to produce a nested array with:
$nested = flatToNested($data);
demo: http://codepad.viper-7.com/HAZxaA