how to sum string values which are coming in array - php

Here is my array
Array
(
[0] => Array
(
[Asan_Name_Val] => 447
[Actual_Ratio] => 15/00/15,04/05/05
)
[1] => Array
(
[Asan_Name_Val] => 447
[Actual_Ratio] => 10/05/11,00/06/05
)
)
The actual ratio value should sum with it values like 15+10=15,00+05=05,15+11=26 .....
So The desired output I want In this format
Array
(
[Asan_Name_Val] => 447
[Actual_Ratio] => 25/05/26,04/11/10
)

Wrote a hacky solution in PHP.
Will work but strongly advice you to optimize.
<?php
$myArray = array(
0 => array(
'Asan_Name_Val' => '447',
'Actual_Ratio' => '15/00/15,04/05/05'
),
1 => array(
'Asan_Name_Val' => '447',
'Actual_Ratio' => '10/05/11,00/06/05'
)
);
$sums = array_fill(0,6,'0');
foreach($myArray as $arr){
$ratio = $arr['Actual_Ratio'];
$j=0;
for($i=0;$i<6;$i++){
$sums[$i] = sprintf("%02d", $sums[$i]+substr($ratio,$j,2));
$j = $j+3;
}
}
$finalRatio = "$sums[0]/$sums[1]/$sums[2],$sums[3]/$sums[4]/$sums[5]";
$desiredArray['Asan_Name_Val'] = '447';
$desiredArray['Actual_Ratio'] = $finalRatio;
print_r($desiredArray);

This would be a flexible and clean approach:
<?php
$input = [
[
'Asan_Name_Val' => "447",
'Actual_Ratio' => "15/00/15,04/05/05"
],
[
'Asan_Name_Val' => "447",
'Actual_Ratio' => "10/05/11,00/06/05"
]
];
$output = [];
$formatter = new NumberFormatter('de_DE', NumberFormatter::DECIMAL);
array_walk($input, function($entry) use (&$output, $formatter) {
$values = explode("/", $entry['Actual_Ratio']);
foreach($values as &$value) {
$value = $formatter->parse($value);
}
$output[$entry['Asan_Name_Val']][] = $values;
});
array_walk($output, function(&$entry, $key) use ($formatter) {
for ($i = 0; $i < count($entry[0]); $i++) {
$sums[] = $formatter->format(array_sum(array_column($entry, $i)));
}
$entry = [
'Asan_Name_Val' => $key,
'Actual_Ratio' => implode("/", $sums)
];
});
print_r(array_values($output));
The output obviously is:
Array
(
[0] => Array
(
[Asan_Name_Val] => 447
[Actual_Ratio] => 25/5/26,04/11/10
)
)

Related

PHP: substract values of 2 arrays of different length

Well, I've got two following arrays:
$incomesArr = [
['1605564000' => 121],
['1605736800' => 3.50],
];
$expensesArr = [
['1605736800' => 3.50],
['1605736800' => 3.50],
['1605564000' => 28],
['1605936000' => 50]
];
As you can see from the variable names, these are the expenses and incomes for the current date (it is a timestamp). All I want to do is to generate the "Revenue" data by substracting value of $expensesArr from $incomesArr with corresponding date, and if there is no date, then substract from 0. Also, if there is no corresponding date in the $expensesArr, then substract nothing (or 0).
Basically, I want to achieve the following result:
['1605564000', 93]; // 121 - 28 = 93
['1605736800', -3.50] // 3.50 - 3.50 - 3.50 (since both expenses are for the same date)
['1605936000', -50] // 0 - 50, since there is no income for that day.
Please note, that the output result should be in the ['key', 'value'] format, not the ['key' => 'value'], since I send these data to jQuery Flot (displaying graphs).
I carry about the performance, since there may be kind of significant amount of data and the best way for me to achieve this is without foreach loop, however if it is the only possible option, then foreach it is!
Any help is highly appreciated. Thank you in advance!
P.S. If it would help, then I do this in Laravel, however I don't think that there is a special helper exactly for that, since I already examined the Laravel documentation multiple times :)
My previous attempt was a bit confusing and scary, but here it is:
$newArr = array_merge([$incomesArr, $expensesArr]);
foreach ($incomesArr as $k => $v){
$sub = $v - $expensesArr[$k];
// this is like : array1[1]-array2[1]
}
$finalArr = [];
foreach($newArr as $key => $value) {
var_dump($value);
foreach ($value as $key => $val) {
$finalArr[$key] = ($val[$key] ?? 0) - ($val[$key] ?? 0);
}
}
$incomesArr = [
['1605564000' => 121],
['1605736800' => 3.50],
];
$expensesArr = [
['1605736800' => 3.50],
['1605736800' => 3.50],
['1605564000' => 28],
['1605936000' => 50]
];
// get data
$dataArr = [];
foreach([-1 => $expensesArr, 1 => $incomesArr] as $ratio => $list){
foreach($list as $value){
$time = key($value);
$dataArr[$time] = ($dataArr[$time] ?? 0) + ($value[$time] * $ratio);
}
}
// convert to your format
$finalArr = [];
foreach($dataArr as $time => $value){
$finalArr []= [$time, $value];
}
print_r($finalArr);
Output
Array
(
[0] => Array
(
[0] => 1605736800
[1] => -3.5
)
[1] => Array
(
[0] => 1605564000
[1] => 93
)
[2] => Array
(
[0] => 1605936000
[1] => -50
)
)
I would split it into two functions like so:
$incomesArr = [
['1605564000' => 121],
['1605736800' => 3.50],
];
$expensesArr = [
['1605736800' => 3.50],
['1605736800' => 3.50],
['1605564000' => 28],
['1605936000' => 50]
];
function getTotalByKey($inputArray, $inputKey)
{
$sum = 0;
foreach ($inputArray as $subArray)
foreach ($subArray as $key => $value) {
$sum += $key === $inputKey ? $value : 0;
}
return $sum;
}
function getProfitByKey($incomesArray, $expensesArray, $key){
return getTotalByKey($incomesArray, $key) - getTotalByKey($expensesArray, $key);
}
$profit = getProfitByKey($incomesArr, $expensesArr, 1605736800); // Outputs -3.5
$incomesArr = [
['1605564000' => 121],
['1605736800' => 3.50],
];
$expensesArr = [
['1605736800' => 3.50],
['1605736800' => 3.50],
['1605564000' => 28],
['1605936000' => 50]
];
$tmp = [];
$final = [];
foreach ($incomesArr as $pair)
{
foreach ($pair as $date => $amount)
{
$tmp[$date] = ($tmp[$date] ?? 0) + $amount;
}
}
foreach ($expensesArr as $pair)
{
foreach ($pair as $date => $amount)
{
$tmp[$date] = ($tmp[$date] ?? 0) - $amount;
}
}
print_r($tmp);
foreach ($tmp as $date => $amount)
{
$final[] = [$date, $amount];
}
print_r($final);
Output
Array
(
[1605564000] => 93
[1605736800] => -3.5
[1605936000] => -50
)
Array
(
[0] => Array
(
[0] => 1605564000
[1] => 93
)
[1] => Array
(
[0] => 1605736800
[1] => -3.5
)
[2] => Array
(
[0] => 1605936000
[1] => -50
)
)

balance the arrays for each index

<?php
$teams = [0 => ['players' => ['marie'=>2342,
'paul'=>3632,
'vincent'=>2362,
'pierre'=>7823,
'jean'=>9203]
],
1 => ['players' => []
],
2 => ['players' => []
],
3 => ['players' => []
]
];
$all_teams = array_merge($teams[0]['players'],
$teams[1]['players'],
$teams[2]['players'],
$teams[3]['players']);
$result = array_chunk($all_teams, 1, true);
for ($i = 0; $i <= 3; $i++) {
if (isset($result[$i]) && isset($teams[$i])) {
$teams[$i]['players'] = $result[$i];
}
}
//I want a input of array like
$teams = [0 => ['players' => ['marie'=>2342, 'jean'=>9203]
],
1 => ['players' => ['paul'=>3632]
],
2 => ['players' => ['vincent'=>2362]
],
3 => ['players' => ['pierre'=>7823]
]
];
Hello, I want to add each player on each team to balance the arrays;
the problem with my code, it puts it in the mess and 'jean' does not count in the array and i want the last element to be added too. and find a better way to balance the tables for each incoming element.
You can do something like:
$teams = [0 => ['players' => ['marie'=>2342,'paul'=>3632,'vincent'=>2362,'pierre'=>7823,'jean'=>9203]],
1 => ['players' => []],
2 => ['players' => []],
3 => ['players' => []]
];
//Get all players and put them into a single array
$players = array_reduce(array_column( $teams, 'players' ),'array_merge',array());
$teamCount = count($teams);
//Clear all Teams
foreach($teams as $key => $team) {
$teams[$key]['players'] = array();
}
//Assign the playes to the team using mod
foreach(array_keys($players) as $key => $player ) {
$teams[ $key % $teamCount ]['players'][$player] = $players[$player];
}
This will result to:
Array
(
[0] => Array
(
[players] => Array
(
[marie] => 2342
[jean] => 9203
)
)
[1] => Array
(
[players] => Array
(
[paul] => 3632
)
)
[2] => Array
(
[players] => Array
(
[vincent] => 2362
)
)
[3] => Array
(
[players] => Array
(
[pierre] => 7823
)
)
)
Here is a solution. It counts total players and then redistributes according to how many players you want on a team.
function balanceTeams($teams, $playersPerTeam, $shuffle = NULL){
//Get total players in array
$playerCount = 0;
foreach($teams as $team){
foreach($team['players'] as $player=>$id){
$players[] = array('name' => $player, 'id'=>$id);
}
}
$playerCount = count($players);
if($shuffle){
shuffle($players);
}
//Make your new array
$count = 0;
$team = 0;
for($i = 0; $i < $playerCount; $i += $playersPerTeam){
for($j = 0; $j < $playersPerTeam; $j++){
if($players[$count]['id']){
$results[$team]['players'][$players[$count]['name']] = $players[$count]['id'];
}else {
break;
}
$count++;
}
$team++;
}
return $results;
}
How to use:
$teams = [0 => ['players' => ['marie'=>2342,
'paul'=>3632,
'vincent'=>2362,
'pierre'=>7823,
'jean'=>9203]
],
1 => ['players' => []
],
2 => ['players' => []
],
3 => ['players' => []
]
];
$playersPerTeam = 2;
$shuffle = NULL; //Set to 1 to shuffle.
$results = balanceTeams($teams, $playersPerTeam, $shuffle);
print_r($results);
Outputs:
Array
(
[0] => Array
(
[players] => Array
(
[marie] => 2342
[paul] => 3632
)
)
[1] => Array
(
[players] => Array
(
[vincent] => 2362
[pierre] => 7823
)
)
[2] => Array
(
[players] => Array
(
[jean] => 9203
)
)
)
function:
function mixPlayers($teams)
{
$r = [];
array_walk_recursive($teams, function ($v, $k) use (&$r) {
if (!is_array($v)) {
$r[] = [$k => $v];
}
});
return $r;
}
function assign($players, $need)
{
$res = [];
for ($i = 0; $i < count($players); $i++) {
$index = $i % $need;
$res[$index]['players'] = array_merge(
isset($res[$index]['players']) ? $res[$index]['players'] : [],
$players[$i]
);
}
return $res;
}
usage:
$res = assign( mixPlayers($teams) , 4);
var_export($res);

count the duplicate “usuario_cidade” in multi-dimensional

please help me with a code. I have this multi-dimensional array and need to count the value of usuario_cidade case its same value like this:
array 52 = (2) Cidade_1, (2) Cidade_2, (1) Cidade_3
Array
(
[52] => Array
(
[0] => stdClass Object
(
[funcionario_id] => 52
[usuario_cidade] => Cidade_1
)
[1] => stdClass Object
(
[funcionario_id] => 52
[usuario_cidade] => Cidade_1
)
[2] => stdClass Object
(
[funcionario_id] => 52
[usuario_cidade] => Cidade_2
)
[3] => stdClass Object
(
[funcionario_id] => 52
[usuario_cidade] => Cidade_3
)
[4] => stdClass Object
(
[funcionario_id] => 52
[usuario_cidade] => Cidade_2
)
)
)
Try this code:
//Create object array format as per question scenario for testing...
$arrObject1 = new stdClass();
$arrObject1->funcionario_id = '52';
$arrObject1->usuario_cidade = 'Cidade_1';
$arrObject2 = new stdClass();
$arrObject2->funcionario_id = '52';
$arrObject2->usuario_cidade = 'Cidade_1';
$arrObject3 = new stdClass();
$arrObject3->funcionario_id = '52';
$arrObject3->usuario_cidade = 'Cidade_2';
$arrObject4 = new stdClass();
$arrObject4->funcionario_id = '52';
$arrObject4->usuario_cidade = 'Cidade_3';
$arrObject5 = new stdClass();
$arrObject5->funcionario_id = '52';
$arrObject5->usuario_cidade = 'Cidade_2';
//Finalize array...
$varArray = array('52' => array(
$arrObject1, $arrObject2, $arrObject3, $arrObject4, $arrObject5
));
$arrResult = array();
//Loop until main array...
foreach($varArray AS $arrKey => $arrObjVal){
//Loop for object values...
foreach($arrObjVal AS $ocjKey => $objVal){
//Check for specific key(i.e. value of usuario_cidade) exist into result array...
if(array_key_exists($objVal->usuario_cidade, $arrResult)){
//Increment value if exist...
$arrResult[$objVal->usuario_cidade] = $arrResult[$objVal->usuario_cidade] + 1;
}
else {
//Initialize value of result array...
$arrResult[$objVal->usuario_cidade] = 1;
}
}
}
print('<pre>');
print_r($arrResult);
print('</pre>');
This will give result:
[Cidade_1] => 2
[Cidade_2] => 2
[Cidade_3] => 1
Hope this help you!
Try this..
$your_array = array();
$usuario_cidade = array();
foreach ($your_array as $key => $values){
foreach($values as $value){
$usuario_cidade[$key][$value->usuario_cidade]=isset($usuario_cidade[$key][$value->usuario_cidade]) ? $usuario_cidade[$key][$value->usuario_cidade] : '0' + 1;
}
}
print_r($usuario_cidade);
Hey kindly check this code it is given the same answer as the conditions are given.
$arr = array();
$arr2 = array('funcionario_id' => 52,'usuario_cidade' => 'Cidade_1' );
$arr3 = array('funcionario_id' => 52,'usuario_cidade' => 'Cidade_1' );
$arr4 = array('funcionario_id' => 52,'usuario_cidade' => 'Cidade_2' );
$arr5 = array('funcionario_id' => 52,'usuario_cidade' => 'Cidade_3' );
$arr6 = array('funcionario_id' => 52,'usuario_cidade' => 'Cidade_2' );
$arr = [$arr2,$arr3,$arr4,$arr5,$arr6];
$cidaed = array('Cidade_1' => 0, 'Cidade_2' => 0 , 'Cidade_3' => 0 );
$count = 0;
//echo var_dump($arr);
foreach ($arr as $key => $value) {
foreach ($value as $keys => $values) {
if($keys == 'usuario_cidade')
{
$cidaed[$values] += 1;
}
}
}
echo var_dump($cidaed);
The answer for above will be.
array(3) { ["Cidade_1"]=> int(2) ["Cidade_2"]=> int(2) ["Cidade_3"]=> int(1) }
Can you please check this.
$main_array[52] = array(
0 => array(
'funcionario_id' => 52,
'usuario_cidade' => 'Cidade_1'
),
1 => array(
'funcionario_id' => 52,
'usuario_cidade' => 'Cidade_1'
),
2 => array(
'funcionario_id' => 52,
'usuario_cidade' => 'Cidade_2'
),
3 => array(
'funcionario_id' => 52,
'usuario_cidade' => 'Cidade_3'
),
4 => array(
'funcionario_id' => 52,
'usuario_cidade' => 'Cidade_2'
)
);
$check_array = array();
$count_array = array();
foreach ($main_array as $main){
foreach($main as $data){
if(in_array($data['usuario_cidade'], $check_array)){
$count_array[$data['usuario_cidade']] = $count_array[$data['usuario_cidade']] + 1;
}else{
array_push($check_array,$data['usuario_cidade']);
$count_array[$data['usuario_cidade']] = 1;
}
}
}
foreach($count_array as $key => $value){
echo $key.'='.$value.'<br />';
}
echo "<pre>"; print_r($count_array);

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);
?>

array grouping which contains same fields

I have an array which contains following values.
array(
'dates' => array(
(int) 0 => '2013-04-22',
(int) 1 => '2013-04-23',
),
'publisherName' => array(
(int) 0 => 'Comp1',
(int) 1 => 'Comp2',
),
'loaded' => array(
(int) 0 => (int) 2189,
(int) 1 => (int) 37,
),
'clicks' => array(
(int) 0 => (int) 0,
(int) 1 => (int) 0,
),
'ctr' => array(
(int) 0 => (int) 0,
(int) 1 => (int) 0,
)
)
What I want to produce is getting company based data on different dates like the array below.
How am I able to create an array which is like;
array (
'2013-04-22'=>array(
'publisherName'=>'Comp1',
'loaded'=>2189,
'clicks'=>0,
'ctr'=>0),
'2013-04-23'=>array(
'publisherName'=>'Comp2',
'loaded'=>37,
'clicks'=>0,
'ctr'=>0)
...
)
Which contains daily stats but which comes from publishername field.
Any ideas?
Here's an example that doesn't rely on any keys, the only requirement is that date is the first array in your original array:
// $array is your original array
$dates = array_shift($array);
$output = array();
foreach ($array as $k => $a) {
foreach ($a as $i => $v) {
$output[$i][$k] = $v;
}
}
$output = array_combine($dates, $output);
Let the initial array be $a and the desired array $b;
Code:
$b = array();
$count = 0;
foreach($a['dates'] as $date) {
$b[$date] = array(
'name' => $a['publisherName'][$count],
'loaded'=> $a['loaded'][$count],
'clicks'=> $a['clicks'][$count],
'ctr'=> $a['ctr'][$count]
);
$count++;
}
Result:
Array
(
[2013-04-22] => Array
(
[name] => Comp1
[loaded] => 2189
[clicks] => 0
[ctr] => 0
)
[2013-04-23] => Array
(
[name] => Comp2
[loaded] => 37
[clicks] => 0
[ctr] => 0
)
)
<?php
$data = $yourarray;
$new = array();
foreach($data['dates'] as $key=>$value) {
$new[$value] = array('name'=>$data['publisherName'][$key],'loaded'=>$data['loaded'][$key],'clicks'=>$data['clicks'][$key],'ctr'=>$data['ctr'][$key]);
}
echo '<pre>';
print_r($new);
?>
$newArr = array();
foreach($data['dates'] as $key=>$value) {
$new[$value] = array('name'=>$data['publisherName'][$key],'loaded'=>$data['loaded'][$key],'clicks'=>$data['clicks'][$key],'ctr'=>$data['ctr'][$key]);
}
echo '<pre>';
print_r($newArr);
$new_arr = your array;
$finalArray = array();
foreach($new_arr['dates'] as $key => $value){
$finalArray[$value] = array(
'publisherName'=>$new_arr['publisherName'][$key],
'loaded'=>$new_arr['loaded'][$key],
'clicks'=>$new_arr['clicks'][$key],
'ctr'=>$new_arr['ctr'][$key]
);
}
Output :
Array
(
[2013-04-22] => Array
(
[publisherName] => Comp1
[loaded] => 2189
[clicks] => 0
[ctr] => 0
)
[2013-04-23] => Array
(
[publisherName] => Comp2
[loaded] => 37
[clicks] => 0
[ctr] => 0
)
)

Categories