Code Coverage
 
Classes and Traits
Functions and Methods
Lines
Total
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
CRAP
94.12% covered (success)
94.12%
48 / 51
iaRanger
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
21.09
94.12% covered (success)
94.12%
48 / 51
 iaNumbers2Ranges
0.00% covered (danger)
0.00%
0 / 1
21.09
94.12% covered (success)
94.12%
48 / 51
<?php
namespace ia\Lib;
class iaRanger {
    /*
        $y = $ranged = iaNumbers2Ranges([1,2,3,5,7]); // already sorted
        echo "<h1>Simple array, vector</h1><pre>".print_r($y,true)."</pre>";
        $r=[
            ['a'=>1, 'v'=>100],
            ['a'=>1, 'v'=>101],
            ['a'=>1, 'v'=>102],
            ['a'=>1, 'v'=>103],
            ['a'=>2, 'v'=>104],
            ['a'=>2, 'v'=>105],
            ['a'=>2, 'v'=>108],
            ['a'=>2, 'v'=>109],
            ['a'=>2, 'v'=>110],
        ];
        $x = iaNumbers2Ranges($r, ['a'], 'v'); // already soreted by a,v
        echo "<h1>Ranged keyed array</h1><pre>".print_r($x,true)."</pre>";
    */
    /**
     * Summarize numbers to ranges by keys
     * Data must be orderd by key1,key2,number
     *
     * @param array $data [['key_1'=>'a', 'key_2', 'int'=>2014], ['key_1'=>'a', 'key_2', 'int'=>2015],...]
     * @param array $keys ['key_1', 'key_2', ..]
     * @param string $keyForNumber key to an integer to summarize by range
     * @param string $joinWith default '-' example 1,2,3,4 do "1.$joinWith"."4"
     * @param string $separateBy default ', '  example 1,3  do "1.$separateBy"."3"
     * @param bool $md5Key true use md5 for hashkey, uses key_1\tkey_2\t...
     * @return array|string ['key_1\tkey_2\t'=>['key_1'=>'Winery 1' 'key_2' => 'merlot' => 'vintage'=>'2010-2014, 2015-2016, 2018'], ...]
     * @version 1.1.0
     *
     * @example
     *   $ranged = iaNumbers2Ranges([1,2,3,5,7]); // "1 - 3, 5, 7", notice Data array is sorted
     *   $Data: [['Winery'=>'Casa Madero','Type'=>'red','Variety'=>'Merlot','Vintage'=>2010],...]; // sorted by Winery, Type, Variety, Vintage
     *   $ranged = iaNumbers2Ranges($Data,['Winery','Type','Variety'],'Vintage')
     *
     */
     public static function iaNumbers2Ranges($data, $keys = [], $keyForNumber = null, $joinWith = '-',  $separateBy = ', ', $md5Key = false) {
        if(empty($data)) {
            return '';
        }
        $changed = 0;
        $prevHash = [];
        $van =[];
        $sumarized = [];
        $keyExtractor = array_flip($keys);
        $keyedData = !empty($keys);
        $hash = 'num';
        if($keyForNumber === null) {
            $keyForNumber = 'num';
        }
        $part = ['num'=>false];
        foreach($data as $d) {
            // calculate hash key for this entry
                if($keyedData) {
                    $part = array_intersect_key($d, $keyExtractor);
                    $hash = implode("\t", array_intersect_key($d, $part) );
                    if($md5Key) {
                        $hash = md5($hash);
                    }
                }
            // new hash? initicialize
                if(!isset($sumarized[$hash])) {
                    $sumarized[$hash] = $part;
                }
            // missing Data
                if($keyedData) {
                    if(!isset($d[$keyForNumber])) {
                        if(!isset($sumarized[$hash][$keyForNumber])) {
                            $sumarized[$hash][$keyForNumber] = '';
                        }
                        continue;
                    }
                    $value = $d[$keyForNumber];
                } else {
                    $value = $d;
                }
            if(!isset($prevHash[$hash])) {
                $sumarized[$hash][$keyForNumber] = $value;
                $prevHash[$hash] = is_numeric($value) ? (int)$value : $value;
                $van[$hash] = 1;
                continue;
            }
            $prevTop = $prevHash[$hash];
            if(!is_numeric($value) || !is_numeric($prevTop)) {
                $sumarized[$hash][$keyForNumber] .= $separateBy.$value;
                $van[$hash] = 1;
            } elseif( $prevTop + 1 == $value) {
                //todo ta raron
                if($van[$hash] === 1)
                    $sumarized[$hash][$keyForNumber] .= $separateBy.$value;
                else if($van[$hash] === 2) {
                    $sumarized[$hash][$keyForNumber] = str_replace($separateBy.$prevTop, $joinWith.$value, $sumarized[$hash][$keyForNumber], $changed);
                    if($changed === 0) {
                        $sumarized[$hash][$keyForNumber] .= $joinWith.$value;
                    }
                } else {
                    $sumarized[$hash][$keyForNumber] = str_replace($joinWith.$prevTop, $joinWith.$value, $sumarized[$hash][$keyForNumber], $changed);
                    if($changed === 0) {
                        $sumarized[$hash][$keyForNumber] .= $joinWith.$value;
                    }
                }
                $van[$hash]++;
            } else {
                $sumarized[$hash][$keyForNumber] .= $separateBy.$value;
                $van[$hash] = 1;
            }
            $prevHash[$hash] = is_numeric($value) ? (int)$value : $value;
        }
        return $keyedData ? $sumarized : $sumarized[$hash][$hash];
    }
}