Ever wanted to generate an array with a range of column names for use in Excel file related parsing?
I've wrote a function that starts at the A column and adds column names up until the column you specified.
<?php
/**
* This function creates an array with column names up until the column
* you specified.
*/
function createColumnsArray($end_column, $first_letters = '')
{
$columns = array();
$length = strlen($end_column);
$letters = range('A', 'Z');
// Iterate over 26 letters.
foreach ($letters as $letter) {
// Paste the $first_letters before the next.
$column = $first_letters . $letter;
// Add the column to the final array.
$columns[] = $column;
// If it was the end column that was added, return the columns.
if ($column == $end_column)
return $columns;
}
// Add the column children.
foreach ($columns as $column) {
// Don't itterate if the $end_column was already set in a previous itteration.
// Stop iterating if you've reached the maximum character length.
if (!in_array($end_column, $columns) && strlen($column) < $length) {
$new_columns = createColumnsArray($end_column, $column);
// Merge the new columns which were created with the final columns array.
$columns = array_merge($columns, $new_columns);
}
}
return $columns;
}
?>
Usage:
<?php
// Return an array with all column names from A until and with BI.
createColumnsArray('BI');
?>
range
(PHP 4, PHP 5)
range — ある範囲の整数を有する配列を作成する
パラメータ
- start
-
シーケンスの最初の値。
- limit
-
値が limit に達するまでシーケンスが続きます。
- step
-
step が指定されている場合、それは 要素毎の増加数となります。step は正の数でなければなりません。デフォルトは 1 です。
返り値
start から limit までの整数の配列を返します。
変更履歴
| バージョン | 説明 |
|---|---|
| 5.0.0 | オプションのパラメータ step が追加されました。 |
| 4.1.0 から 4.3.2 | PHP 4.1.0 から 4.3.2 までは、range() は数値文字を文字 (string) として認識し、数値 (integer) としては認識しません。 その代わり、文字列シーケンスが使用されます。例えば、 "4242" は "4" として扱われます。 |
| 4.1.0 | 4.1.0 より前のバージョンでは、range() 関数は、 昇順の整数配列のみを生成しました。 文字シーケンス及び降順の配列のサポートが 4.1.0 で追加されました。 文字のシーケンスは一文字のみに限定されます。それより長い文字が指定された場合は、 最初の文字のみが使用されます。 |
例
例1 range() の例
<?php
// array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)
foreach (range(0, 12) as $number) {
echo $number;
}
// step 引数は PHP 5.0.0 以降で使用できます
// array(0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100)
foreach (range(0, 100, 10) as $number) {
echo $number;
}
// 文字列シーケンスは PHP 4.1.0 以降で使用できます
// array('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i');
foreach (range('a', 'i') as $letter) {
echo $letter;
}
// array('c', 'b', 'a');
foreach (range('c', 'a') as $letter) {
echo $letter;
}
?>
dries at volta dot be
09-Feb-2012 04:30
Aram Kocharyan
27-Feb-2011 12:58
Here's a function to generate ranges from strings:
<?php
/* Creates an array of integers based on a given range string of format "int - int"
Eg. range_str('2 - 5'); */
function range_str($str) {
preg_match('#(\\d+)\\s*-\\s*(\\d+)#', $str, $matches);
if ( count($matches) == 3 ) {
return range($matches[1], $matches[2]);
}
return FALSE;
}
// Test
$array = range_str(' 2 - 4 ');
print_r($array);
?>
This outputs:
Array
(
[0] => 2
[1] => 3
[2] => 4
)
jay at NOspam dot myd3 dot com
29-Apr-2009 11:54
This is a modified version of thomas' range_string() function. It's simpler, cleaner, and more robust, but it lacks the advanced features his function had, hopefully it will be of assitance to someone.
Examples:
input: "1, 2, 3, 4, 5, 6" --> output: 1, 2, 3, 4, 5, 6
input: "1-6" --> output: 1, 2, 3, 4, 5, 6
input: "1-6" --> output: 1, 2, 3, 4, 5, 6
input: "1 - -6" --> output: 1, 2, 3, 4, 5, 6
input: "0 - 0" --> output: 0
input: "1, 4-6, 2" --> output: 1, 2, 4, 5, 6
input: "6,3-1" --> output: 1, 2, 3, 6
<?php
define('RANGE_ARRAY_SORT', 1);
define('RANGE_ARRAY', 2);
define('RANGE_STRING_SORT', 3);
define('RANGE_STRING', 4);
function range_string($range_str, $output_type = RANGE_ARRAY_SORT)
{
// Remove spaces and nother non-essential characters
$find[] = "/[^\d,\-]/";
$replace[] = "";
// Remove duplicate hyphens
$find[] = "/\-+/";
$replace[] = "-";
// Remove duplicate commas
$find[] = "/\,+/";
$replace[] = ",";
$range_str = preg_replace($find, $replace, $range_str);
// Remove any commas or hypens from the end of the string
$range_str = trim($range_str,",-");
$range_out = array();
$ranges = explode(",", $range_str);
foreach($ranges as $range)
{
if(is_numeric($range) || strlen($range) == 1)
{
// Just a number; add it to the list.
$range_out[] = (int) $range;
}
else if(is_string($range))
{
// Is probably a range of values.
$range_exp = preg_split("/(\D)/",$range,-1,PREG_SPLIT_DELIM_CAPTURE);
$start = $range_exp[0];
$end = $range_exp[2];
if($start > $end)
{
for($i = $start; $i >= $end; $i -= 1)
{
$range_out[] = (int) $i;
}
}
else
{
for($i = $start; $i <= $end; $i += 1)
{
$range_out[] = (int) $i;
}
}
}
}
switch ($output_type) {
case RANGE_ARRAY_SORT:
$range_out = array_unique($range_out);
sort($range_out);
case RANGE_ARRAY:
return $range_out;
break;
case RANGE_STRING_SORT:
$range_out = array_unique($range_out);
sort($range_out);
case RANGE_STRING:
default:
return implode(", ", $range_out);
break;
}
}
// Sample Usage:
$range = range_string("6, 3-1");
?>
thomas+php1 at tgohome dot com
30-Sep-2008 02:44
Range as a string. Items are separated with a comma; which can be in any of the following formats:
"1, 2, 3, 4, 5, 6" - output: 1, 2, 3, 4, 5, 6
"1 - 6" - output: 1, 2, 3, 4, 5, 6
"1 -%2 6" - output: 1, 3, 5 (last number will not be counted unless it evenly fits in)
"1 - -6" - output: 1, 0, -1, -2, -3, -4, -5, -6
"0 - 0" - output: 0
"1, 2, 3, [LAST_NUM] - 6" - output: 1, 2, 3, 3, 4, 5, 6 (note repeated 3)
"1, 2, 3, [LAST_NUM+1] - 6" - output: 1, 2, 3, 4, 5, 6 (no repeated 3)
"1, 2, 3, [LAST_NUM+-1] - 6" - output: 1, 2, 3, 2, 3, 4, 5, 6
<?php
define('RANGE_ARRAY', 1);
define('RANGE_STRING', 2);
function range_string($range_str, $output_type = RANGE_ARRAY)
{
$range_out = array();
$ranges = explode(",", $range_str);
$last_num = 0;
foreach($ranges as $range)
{
$step = 1;
$range = trim($range);
if(is_numeric($range))
{
// Just a number; add it to the list.
$range_out[] = $range;
$last_num = $range;
}
else if(is_string($range))
{
// Figure out if it is just a character.
if(strlen($range) == 1)
{
$range_out[] = (string)$range;
$last_num = 0;
}
else
{
// Is probably a range of values.
$range_exp = explode(" ", $range);
if(substr($range_exp[1], 0, 1) == '-' && !is_numeric(substr($range_exp[1], 0, 1)))
{
// Jumping range?
$jump = str_split($range_exp[1], 1);
if(count($jump) > 0)
{
if($jump[1] == '%')
{
$step = substr($range_exp[1], 2);
}
}
else
{
// Normal range.
$step = 1;
}
}
else
{
$step = 1;
}
if($range_exp[0] == '[LAST_NUM]')
{
$start = $last_num;
}
else
{
$exp = explode("+", $range_exp[0]);
if($exp[0] == '[LAST_NUM')
{
$start = $last_num + trim($exp[1], ']');
}
else
{
$start = $range_exp[0];
}
}
$end = $range_exp[2];
if($start > $end)
{
for($i = $start; $i >= $end; $i -= $step)
{
$range_out[] = $i;
}
$last_num = $i;
}
else
{
for($i = $start; $i <= $end; $i += $step)
{
$range_out[] = $i;
}
$last_num = $i;
}
// echo $step . ", ";
}
}
}
if($output_type == RANGE_ARRAY)
{
return $range_out;
}
else
{
return implode(", ", $range_out);
}
}
echo range_string("1, 2, 3, [LAST_NUM+1] - 6", RANGE_STRING);
?>
ThinkMedical at Gmail dot com
25-Aug-2008 11:11
foreach(range()) whilst efficiant in other languages, such as python, it is not (compared to a for) in php*.
php is a C-inspired language and thus for is entirely in-keeping with the lanuage aethetic to use it
<?php
//efficiant
for($i = $start; $i < $end; $i+=$step)
{
//do something with array
}
//inefficiant
foreach(range($start, $end, $step) as $i)
{
//do something with array
}
?>
That the officiant documentation doesnt mention the for loop is strange.
Note however, that in PHP5 foreach is faster than for when iterating without incrementing a variable.
* My tests using microtime and 100 000 iterations consistently (~10 times) show that for is 4x faster than foreach(range()).
captvanhalen at gmail dot com
27-Mar-2008 04:33
Here is a home rolled range() function that uses the step feature for those unfortunate souls who cannot use PHP5:
<?php
function my_range( $start, $end, $step = 1) {
$range = array();
foreach (range( $start, $end ) as $index) {
if (! (($index - $start) % $step) ) {
$range[] = $index;
}
}
return $range;
}
?>
chris at laflash dot org
09-May-2007 10:47
Quick HTML menus with minimum and maximum sets of years:
<?php
/*
** Quick HTML menus with minimum and maximum sets of years.
** @author Chris Charlton <chris@laflash.org>
** @license FREE!
*/
// Years range setup
$year_built_min = 1900;
$year_built_max = date("Y");
?>
<select id="yearBuiltMin" size="1">
<?php // Generate minimum years
foreach (range($year_built_min, $year_built_max) as $year) { ?>
<option value="<?php echo($year); ?>"><?php echo($year); ?></option>
<?php } ?>
</select>
<select id="yearBuiltMax" size="1">
<?php // Generate max years
foreach (range($year_built_max, $year_built_min) as $year) { ?>
<option value="<?php echo($year); ?>"><?php echo($year); ?></option>
<?php } ?>
</select>
m0sh3 at hotmail dot com
01-Mar-2007 10:46
Here's how i use it to check if array is associative or not:
<?php
if (array_keys($arr)===range(0, sizeof($arr)-1)) {
// not associative array
} else {
// associative array
}
?>
manuel at levante dot de
06-Nov-2006 10:25
<?php
function srange ($s) {
preg_match_all("/([0-9]{1,2})-?([0-9]{0,2}) ?,?;?/", $s, $a);
$n = array ();
foreach ($a[1] as $k => $v) {
$n = array_merge ($n, range ($v, (empty($a[2][$k])?$v:$a[2][$k])));
}
return ($n);
}
$s = '1-4 6-7 9-10';
print_r(srange($s));
?>
Return:
Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 4
[4] => 6
[5] => 7
[6] => 9
[7] => 10
)
subscription101 at hotmail dot com
07-Jan-2006 11:36
A much simpler way of creating a range of even numbers is by starting with an even number:
<?php
range(2, 10, 2);
?>
emory underscore smith at hotmail
20-Aug-2005 01:53
since its not stated explicitly above, thought id point out that you arent limited to using integers.
however, be careful when doing so, as you might not get the range you expect!
to illustrate:
<?php
$am = range(500,1600,10);
$fm = range(88.1,107.9,.2);
print_r($am);
print_r($fm);
?>
print_r($am) yields the expected result:
Array
(
[0] => 500
[1] => 510
[2] => 520
...
[109] => 1590
[110] => 1600
)
print_r($fm), however, falls a bit (1%) short:
Array
(
[0] => 88.1
[1] => 88.3
[2] => 88.5
...
[97] => 107.5
[98] => 107.7
)
so, if you want to use a non-integral step size params for numeric ranges, be sure to account for fp representation accuracy and error accumulation; a step size of something like pi or 1/10 could spell disaster for a large range. if in doubt, use integral steps and divide ... something like <?php range(88.1,108,.2) ?> might work to recover 107.9, but would not be scalable like, say <?php array_map(create_function('$x','return $x/10;'),range(881,1079,2)) ?>.
-emory
derek at php dot net
08-May-2005 12:13
This should emulate range() a little better.
<?php
function range_wroar($low, $high, $step = 1) {
$arr = array();
$step = (abs($step)>0)?abs($step):1;
$sign = ($low<=$high)?1:-1;
if(is_numeric($low) && is_numeric($high)) {
//numeric sequence
for ($i = (float)$low; $i*$sign <= $high*$sign; $i += $step*$sign)
$arr[] = $i;
} else {
//character sequence
if (is_numeric($low))
return $this->range($low, 0, $step);
if (is_numeric($high))
return $this->range(0, $high, $step);
$low = ord($low);
$high = ord($high);
for ($i = $low; $i*$sign <= $high*$sign; $i += $step*$sign) {
$arr[] = chr($i);
}
}
return $arr;
}
?>
j dot gizmo at aon dot at
22-Sep-2004 10:23
i figured i'd add some more functionality to the myRange() functions below.
now you can, besides giving a $step parameter,
1. count backwards
2. count with letters
3. give whatever parameter you want, there's nothing (i know of) that will cause an endless loop (try a negative $step for the previous function....)
<?php
function myRange($num1, $num2, $step=1)
{
if (is_numeric($num1) && is_numeric($num2))
{
//we have a numeric range
$step = ( abs($step)>0 ? abs($step) : 1 ); //make $step positive
$dir = ($num1<=$num2 ? 1 : -1); //get the direction
for($i = (float)$num1; $i*$dir <= $num2*$dir; $i += $step*$dir)
{
$temp[] = $i;
}
}
else
{
//we have a character range
$num1=ord((string)$num1); //convert to ascii value
$num2=ord((string)$num2);
$step = ( abs($step)>0 ? abs($step) : 1 ); //make $step positive
$dir = ($num1<=$num2 ? 1 : -1); //get direction
for($i = $num1; $i*$dir <= $num2*$dir; $i += $step*$dir)
{
$temp[] = chr($i);
}
}
return $temp;
}
print_r(myRange( 1, 3, 0.5 )); //you can use fractional steps
print_r(myRange( "a", "k", 3 )); //or count letters
print_r(myRange( "5", "9" )); //numbers are detected even if hidden in strtings
print_r(myRange( "!", "%", 1/pi() )); //or mess around with senseless parameters
?>
donwilson at gmail dot com
31-Aug-2004 03:38
To speed your MyRange() function, I have created a much nicer function with less code to sift through to include the step parameter.
<?php
// range() limitation for PHP <5.0.0
function myRange($num1, $num2, $step=1)
{
for($i = $num1; $i <= $num2; $i += $step)
{
$temp[] = $i;
}
return $temp;
}
?>
For whatever reason my comment was deleted..?
Forrester at tfcustomized dot com
17-May-2004 01:57
Since users of < PHP 5.0.0 don't have the option of the step parameter, I've created a little function to account for it:
@USAGE: (int low, int high [, int step])
function myRange($low,$high,$step=1)
{
$ranArray = range($low,$high);
$step--;
$keys = count($ranArray);
for($i=0;$i<$keys;$i++)
{
$retArray[] = $ranArray[$i];
$i = $i + $step;
}
return $retArray;
}
// Example usage:
print_r(myRange(1,11,2));
// Returns the array:
// [0] => 1
// [1] => 3
// [2] => 5
// [3] => 7
// [4] => 9
// [5] => 11
