I have data im getting from mongodb to arrays and I want to work on the return data to split it by date and some other value , this is what I got so far and I need some help with the results
<?php
$stats=array(
array("source"=>501,"status"=>"answered","dest"=>"100","date"=>"2022-17-01"),
array("source"=>501,"status"=>"noAnswer","dest"=>"120","date"=>"2022-17-01"),
array("source"=>501,"status"=>"answered","dest"=>"100","date"=>"2022-18-01"),
array("source"=>502,"status"=>"answered","dest"=>"120","date"=>"2022-17-01"),
array("source"=>502,"status"=>"answered","dest"=>"130","date"=>"2022-17-01"),
array("source"=>502,"status"=>"answered","dest"=>"110","date"=>"2022-18-01")
);
$new1 = array();
$answer = 0;
$noanswer = 0;
$lastsrc = '';
$lastdate = '';
$dest=0;
foreach ($stats as $new) {
$src = $new['source'];
$date = $new['date'];
if ( $lastsrc == $src && $lastdate == $date ) {
$dest ;
if($new['status'] == 'answered'){ $answer ; }
if($new['status'] == 'noanswer'){ $noanswer ;}
$new1[] = array('source' => $src,
'date' => $date,
'ans' => $answer,
'nonans' => $noanswer,
'dest' => $dest );
} else if ( $lastsrc == $src && $lastdate != $date ) {
$dest ;
if($new['status'] == 'answered'){ $answer ;}
if($new['status'] == 'noanswer'){ $noanswer ;}
$new1[] = array('source' => $src,
'date' => $date,
'ans' => $answer,
'nonans' => $noanswer,
'dest' => $dest );
} else {
$dest ;
if($new['status'] == 'answered'){ $answer ; }
if($new['status'] == 'noanswer'){ $noanswer ;}
$new1[] = array('source' => $src,
'date' => $date,
'ans' => $answer,
'nonans' => $noanswer,
'dest' => $dest );
$lastsrc = $src;
$lastdate = $date;
}
}
print_r($new1);
?>
what im trying to achieve is splitting the Data by date and by source as well, so if in foreach loop I found same source and same date then I modify the array instead of create new array, if its the opposite then create new array
the result im trying to get is :
array("source"=>501,"ans"=>"1","noans" => 0,"dest"=>1,"date"=>"2022-17-01"),
array("source"=>501,"ans"=>"1","noAnswer" => 1,"dest"=>2,"date"=>"2022-18-01"),
array("source"=>502,"ans"=>"2","noans" => 0,"dest"=>2,"date"=>"2022-17-01"),
array("source"=>502,"ans"=>"1","noans" => 0,"dest"=>1,"date"=>"2022-18-01")
im not sure if its the right way ,any help will be very appreciated thanks
CodePudding user response:
<?php
$stats = [
[ 'source' => 501, 'status' => 'answered', 'dest' => '100', 'date' => '2022-17-01' ],
[ 'source' => 501, 'status' => 'noAnswer', 'dest' => '120', 'date' => '2022-17-01' ],
[ 'source' => 501, 'status' => 'answered', 'dest' => '100', 'date' => '2022-18-01' ],
[ 'source' => 502, 'status' => 'answered', 'dest' => '120', 'date' => '2022-17-01' ],
[ 'source' => 502, 'status' => 'answered', 'dest' => '130', 'date' => '2022-17-01' ],
[ 'source' => 502, 'status' => 'answered', 'dest' => '110', 'date' => '2022-18-01' ]
];
$result = [];
foreach ($stats as $stat) {
$source = $stat['source'];
$date = $stat['date'];
$closure = static fn($item) => $item['source'] === $source && $item['date'] === $date;
$found = array_filter($result, $closure);
if (count($found) === 0) {
$list = array_filter($stats, $closure);
$list = array_map(static fn($item) => [ 'status' => $item['status'], 'dest' => $item['dest'] ], $list);
$result[] = [
'source' => $source,
'date' => $date,
'answered' => count(array_filter(array_column($list, 'status'), static fn($item) => $item === 'answered')),
'noAnswer' => count(array_filter(array_column($list, 'status'), static fn($item) => $item === 'noAnswer')),
'dest' => count(array_column($list, 'dest')),
];
}
}
print_r($result);
CodePudding user response:
Create a composite key from the fields you want to sort by and use an associative array. (A single level in the array makes sorting/merging as well as extracting the values(array_values()) afterwards easy) Then you only need to iterate over $stats and $result once each.
$result = [];
foreach($stats as $stat) {
$key = $stat['source'].'_'.$stat['date'];
if (!array_key_exists($key, $result)) {
$result[$key] = ['answered' => 0, 'noAnswer' => 0] $stat;
}
$result[$key][$stat['status']] ;
$result[$key]['dest'][$stat['dest']] = 1;
}
$result = array_map( // Transform "destinations key store" to count
function($item) {
$item['dest'] = count($item['dest']); return $item;
},
$result
);
print_r(array_values($result));
['source' => 501, 'status' => answered, 'dest' => 2, 'date' => 2022-17-01, 'answered' => 1, 'noAnswer' => 1],
['source' => 501, 'status' => answered, 'dest' => 1, 'date' => 2022-18-01, 'answered' => 1, 'noAnswer' => 0],
['source' => 502, 'status' => answered, 'dest' => 2, 'date' => 2022-17-01, 'answered' => 2, 'noAnswer' => 0],
['source' => 502, 'status' => answered, 'dest' => 1, 'date' => 2022-18-01, 'answered' => 1, 'noAnswer' => 0]
