Home > Back-end >  Grouping of same values in an array
Grouping of same values in an array

Time:05-19

I have this array with year as its key and count as its value,

$dateRange = array([
   "1990" => 10,
   "1991" => 12,
   "1992" => 12,
   "1993" => 12,
   "1994" => 12,
   "1995" => 12,
   "1996" => 6
]);

and how can I make it look like this (getting consecutive year/s with a count/value of 12 then count its total value)

$dateRange = ([
    "1990" => 10,
    "1991-1995" => 60,
    "1996" => 6
]);

CodePudding user response:

I came up with the following solutions, it's not efficient with large data but will work. 1991-1995 will be string though.

      $dateRange = array([
        1990 => 10,
        1991 => 12,
        1992 => 12,
        1993 => 12,
        1994 => 12,
        1995 => 12,
        1996 => 6
      ]);
  
      dump($dateRange[0]);
      
      $first = reset($dateRange[0]);
      $last  = end($dateRange[0]);
      $newArr = array([]);
      $sum = 0;
      $firstRange = null;
      $lastRange = null;
      foreach($dateRange[0] as $key => $item){
        if($item == $first){
            $newArr[0][$key] = $item;
        }
        elseif($item == $last){
            $newArr[0][$firstRange.'-'.$lastRange] = $sum;
            $newArr[0][$key] = $item;
        }
        else{
            if($firstRange == null){
                $firstRange = $key;
            }
            $lastRange = $key;
            $sum  = $item;
        }
      }
      dd($newArr[0]);

CodePudding user response:

Loop through each individual dataset(subarray) and

  • Sort the keys numerically.

  • Compare every current key with previous key to check if they are consecutive.

    If prev_key 1 == curr_key, then they are consecutive, else they are not.

  • Check the same for their values' equality as well.

  • In either step 2 or 3, if any of the conditions don't match, add the current range and it's sum to the result and start a new range from this index. Likewise, collect all the results.

Snippet:

<?php

$res = [];

foreach($dateRange as $k => $v){
    $temp = [];
    $keys = array_keys($v);
    sort($keys, SORT_NUMERIC);
    $prev = 0;
    $sum = 0;
    for($i = 0; $i < count($keys);   $i){
        if($i > 0 && ($keys[ $i - 1 ]   1 != $keys[ $i ] || $v[ $keys[ $i - 1 ] ] !== $v[ $keys[ $i ] ])){
            if($prev == $i - 1) $temp[ $keys[ $prev ]] = $sum;
            else $temp[ $keys[$prev] . "-" . $keys[$i - 1]] = $sum;
            $sum = 0;
            $prev = $i;
        }
        
        $sum  = $v[$keys[ $i ]];
        if($i === count($keys) - 1){
            if($prev == $i) $temp[ $keys[ $prev ]] = $sum;
            else $temp[ $keys[$prev] . "-" . $keys[ $i ]] = $sum;
        }
    }
    $res[] = $temp;
}


print_r($res);

Online Demo

  • Related