Skip to content

Instantly share code, notes, and snippets.

@abcarroll
Created December 13, 2015 18:32
Show Gist options
  • Save abcarroll/4818769b0959d15260c3 to your computer and use it in GitHub Desktop.
Save abcarroll/4818769b0959d15260c3 to your computer and use it in GitHub Desktop.
<?php
/*
* (C) Copyright 2015 A.B. Carroll <[email protected]>. MIT or BSD License - your choice.
*/
require 'Utility.php';
$tests = [
'1, 3, 5, 7, 9, 11, 13-15' => [1, 3, 5, 7, 9, 11, 13, 14, 15],
'1-5' => [1, 2, 3, 4, 5],
'7-10' => [7, 8, 9, 10],
'1-3' => [1, 2, 3],
'1-5, 10-12' => [1, 2, 3, 4, 5, 10, 11, 12],
'1-5, 7' => [1, 2, 3, 4, 5, 7],
'10, 12-15' => [10, 12, 13, 14, 15],
'10, 12-15, 101' => [10, 12, 13, 14, 15, 101],
'1-5, 7, 10-12' => [1, 2, 3, 4, 5, 7, 10, 11, 12],
'1-5, 7, 10-12, 101' => [1, 2, 3, 4, 5, 7, 10, 11, 12, 101],
'1-5, 7, 10, 12, 14' => [1, 2, 3, 4, 5, 7, 10, 12, 14],
'1-4, 7, 10-12, 101' => '1,2,3,4,7,10,11,12,101',
'1-3, 5.5, 7, 10-12, 101' => '1,2,3,5.5,7,10,11,12,101',
];
foreach($tests as $expectedResult => $array) {
$funcResult = Utility::rangeToStr($array);
if($funcResult != $expectedResult) {
echo "Failed: result '$funcResult' != test check '$expectedResult'\n";
} else {
echo "Passed!: '$funcResult' == '$expectedResult'\n";
}
}
<?php
/*
* (C) Copyright 2015 A.B. Carroll <[email protected]>. MIT or BSD License - your choice.
*/
class Utility {
/**
* Converts either a array of integers or string of comma-separated integers to a natural english range, such as "1,2,3,5" to "1-3, 5". It also supports
* floating point numbers, however with some perhaps unexpected / undefined behaviour if used within a range.
*
* @param string|array $items Either an array (in any order, see $sort) or a comma-separated list of individual numbers.
* @param string $itemSep The string that separates sequential range groups. Defaults to ', '.
* @param string $rangeSep The string that separates ranges. Defaults to '-'. A plausible example otherwise would be ' to '.
* @param bool|true $sort Sort the array prior to iterating? You'll likely always want to sort, but if not, you can set this to false.
*
* @return string
*/
static public function rangeToStr($items, $itemSep = ', ', $rangeSep = '-', $sort = true) {
if(!is_array($items)) {
$items = explode(',', $items);
}
if($sort) {
sort($items);
}
$point = null;
$range = false;
$str = '';
foreach($items as $i) {
if($point === null) {
$str .= $i;
} elseif(($point + 1) == $i) {
$range = true;
} else {
if($range) {
$str .= $rangeSep . $point;
$range = false;
}
$str .= $itemSep . $i;
}
$point = $i;
}
if($range) {
$str .= $rangeSep . $point;
}
return $str;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment