Home > Blockchain >  split arrays by date and other identifier
split arrays by date and other identifier

Time:01-19

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]
  •  Tags:  
  • Related