Search code examples
phparraysmultidimensional-arrayarray-sum

multidimensional array sum and put into single column depending on key value


To-date and from-date has to be chosen. I have one array having key as date what i want is if i select 15 days key values up to 15 will be adding and come to one column so if my to-date and from-date difference is 30 so it will come two column 1-15 / 16-30 and the values will be added and sit according

    Array
    (
        [2018-08-01] => Array
            (
                [male] => 3
                [female] => 0
            )

        [2018-08-02] => Array
            (
                [male] => 1
                [female] => 0
            )

        [2018-08-06] => Array
            (
                [male] => 6
                [female] => 2
            )



        [2018-08-11] => Array
            (
                [male] => 1
                [female] => 1
            )

        [2018-08-17] => Array
            (
                [male] => 3
                [female] => 2
            )

        [2018-08-18] => Array
            (
                [male] => 3
                [female] => 3
            )

        [2018-08-03] => Array
            (
                [male] => 2
                [female] => 0
            )

        [2018-08-04] => Array
            (
                [male] => 4
                [female] => 3
            )
    )

1-15 dates will be get sum values and 16-30 will get another sum value so how many month will be there like that it will be come 1-15/16-30 manner

This answer is perfectly working


    $partitions = 2;

$s_day = 1;
$intervals = [];

while (end($intervals)['to'] != 31) {
   $e_tmp = $s_day + (int)(31/$partitions) - 1;
   $e_day = $e_tmp > 31 ? 31 : $e_tmp;
   $intervals[] = ['from' => $s_day, 'to' => $e_day];
   $s_day = $e_day + 1;
}

// partition info by intervals
$info_partitioned = [];
foreach ($generesult as $date => $info) {
   // parse month and day
   preg_match('/(\d+-\d+)-(\d+)/', $date, $matches);

   // choose interval
   $found = null;
   foreach ($intervals as $days) {
      if ($matches[2] >= $days['from'] && $matches[2] <= $days['to']) {
         $found = ' : ' . $days['from'] . '-' . $days['to'];
         break;
      }
   }

   // put info into required partition
   $info_partitioned[$matches[1] . $found][] = $info;
}

// sum males/females in each partition
$results = [];
foreach ($info_partitioned as $partition => $counts) {
   foreach($counts as $stat) {
      $results[$partition]['male'] += $stat['male'];
      $results[$partition]['female'] += $stat['female'];
   }
}

print_r($results); 

sample outputs


Solution

  • If I correctly understood you - you want to split gender info into equal partitions of the exact month and sum these gender counts in partitions. This is the code which I came up with:

    // gender data
    $data = [ 
           '2018-08-01' =>  ['male' => 3, 'female' => 0] ,
           '2018-08-02' =>  ['male' => 1, 'female' => 0] ,
           '2018-08-06' =>  ['male' => 6, 'female' => 2] ,
           '2018-08-11' =>  ['male' => 1, 'female' => 1] ,
           '2018-08-17' =>  ['male' => 3, 'female' => 2] ,
           '2018-08-18' =>  ['male' => 3, 'female' => 3] ,
           '2018-08-03' =>  ['male' => 2, 'female' => 0] ,
           '2018-08-04' =>  ['male' => 4, 'female' => 3] ,
            ];
    
    // construct day interval partitions in a month
    $partitions = 2;
    
    $s_day = 1;
    $intervals = [];
    
    while (end($intervals)['to'] != 30) {
       $e_tmp = $s_day + (int)(30/$partitions) - 1;
       $e_day = $e_tmp > 30 ? 30 : $e_tmp;
       $intervals[] = ['from' => $s_day, 'to' => $e_day];
       $s_day = $e_day + 1;
    }
    
    // partition info by intervals
    $info_partitioned = [];
    foreach ($data as $date => $info) {
       // parse month and day
       preg_match('/(\d+-\d+)-(\d+)/', $date, $matches);
    
       // choose interval
       $found = null;
       foreach ($intervals as $days) {
          if ($matches[2] >= $days['from'] && $matches[2] <= $days['to']) {
             $found = ' : ' . $days['from'] . '-' . $days['to'];
             break;
          }
       }
    
       // put info into required partition
       $info_partitioned[$matches[1] . $found][] = $info;
    }
    
    // sum males/females in each partition
    $results = [];
    foreach ($info_partitioned as $partition => $counts) {
       foreach($counts as $stat) {
          $results[$partition]['male'] += $stat['male'];
          $results[$partition]['female'] += $stat['female'];
       }
    }
    
    var_dump($results);
    

    Partitions = 2, outputs :

    array(2) {
      ["2018-08 : 1-15"]=>
      array(2) {
        ["male"]=>
        int(17)
        ["female"]=>
        int(6)
      }
      ["2018-08 : 16-30"]=>
      array(2) {
        ["male"]=>
        int(6)
        ["female"]=>
        int(5)
      }
    }
    

    Partitions = 4, outputs:

    array(3) {
      ["2018-08 : 1-7"]=>
      array(2) {
        ["male"]=>
        int(16)
        ["female"]=>
        int(5)
      }
      ["2018-08 : 8-14"]=>
      array(2) {
        ["male"]=>
        int(1)
        ["female"]=>
        int(1)
      }
      ["2018-08 : 15-21"]=>
      array(2) {
        ["male"]=>
        int(6)
        ["female"]=>
        int(5)
      }
    }
    

    Try it online!