(PHP 4, PHP 5, PHP 7, PHP 8)
range — Create an array containing a range of elements
DescriptionIf both start
and end
are strings, and step
is int the produced array will be a sequence of bytes. Otherwise, the produced array will be a sequence of numbers.
The sequence is increasing if start
is less than equal to end
. Otherwise, the sequence is decreasing.
start
First value of the sequence.
end
Last possible value of the sequence.
step
step
indicates by how much is the produced sequence progressed between values of the sequence.
step
may be negative for decreasing sequences.
If step
is a float without a fractional part, it is interpreted as int.
Returns a sequence of elements as an array with the first element being start
going up to end
, with each value of the sequence being step
values apart.
The last element of the returned array is either end
or the previous element of the sequence, depending on the value of step
.
If both start
and end
are strings, and step
is int the produced array will be a sequence of bytes, generally latin ASCII characters.
If at least one of start
, end
, or step
is float the produced array will be a sequence of float.
Otherwise, the produced array will be a sequence of int.
Errors/Exceptionsstep
is 0
, a ValueError is thrown. start
, end
, or step
is not is_finite(), a ValueError is thrown. step
is negative, but the produced range is increasing (i.e. $start <= $end
), a ValueError is thrown. start
or end
is the empty string ''
, an E_WARNING
is emitted and the empty string will be interpreted as 0
. start
or end
is a non-numeric string with more than one byte, an E_WARNING
is emitted. start
or end
is a string that is implicitly cast to an int because the other boundary value is a number, an E_WARNING
is emitted. step
is a float, and start
and end
are non-numeric string, an E_WARNING
is emitted. start
and end
are strings then range() will now always produce an array of bytes. Previously if one of the boundary values was a numeric string, then the other boundary value was implicitly cast to int. 8.3.0 An E_WARNING
is now emitted if start
or end
is a string that is implicitly cast to int because the other boundary value is a number. 8.3.0 An E_WARNING
is now emitted if start
or end
is a non-numeric string with more than one byte. 8.3.0 An E_WARNING
is now emitted if start
or end
is the empty string. 8.3.0 If step
is a float with no fractional part, it will be interpreted as an int. 8.3.0 A ValueError is now thrown if step
is negative when producing an increasing range. 8.3.0 A ValueError is now thrown if step
is not finite. 8.3.0 A TypeError is now thrown if start
or end
is an array, object, or resource. Previously they were implicitly cast to int. Examples
Example #1 range() examples
<?php
echo implode(', ', range(0, 12)), PHP_EOL;
echo
implode(', ', range(0, 100, 10)), PHP_EOL;
echo
implode(', ', range('a', 'i')), PHP_EOL;
echo
implode(', ', range('c', 'a')), PHP_EOL;
echo
implode(', ', range('A', 'z')), PHP_EOL;
?>
The above example will output:
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 a, b, c, d, e, f, g, h, i c, b, a A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, [, \, ], ^, _, `, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, zPalz ¶
12 years ago
To create a range array like
Array
(
[11] => 1
[12] => 2
[13] => 3
[14] => 4
)
combine two range arrays using array_combine:
array_combine(range(11,14),range(1,4))
php at keith tyler dot com ¶
11 years ago
So with the introduction of single-character ranges to the range() function, the internal function tries to be "smart", and (I am inferring from behavior here) apparently checks the type of the incoming values. If one is numeric, including numeric string, then the other is treated as numeric; if it is a non-numeric string, it is treated as zero.
But.
If you pass in a numeric string in such a way that is is forced to be recognized as type string and not type numeric, range() will function quite differently.
Compare:
<?php
echo implode("",range(9,"Q"));
echo implode("",range("9 ","Q")); echo implode("",range("q","9 "));
?>=<;:987654
?>
I wouldn't call this a bug, because IMO it is even more useful than the stock usage of the function.
gtisza at gmail dot com ¶
12 years ago
You might expect range($n, $n-1) to be an empty array (as in e.g. Python) but actually PHP will assume a step of -1 if start is larger than end.
9 years ago
The function will generate an array of integers even if your numerical parameters are enclosed in quotes.
<?php
var_dump( range('1', '2') ); ?>
An easy way to get an array of strings is to map strval() to the range:
<?php
var_dump( array_map('strval', range('1', '2')) ); ?>
9 years ago
The function "range" is very useful to get an array of characters as range('C','R') does.
At work, I had to extend the function range($a,$b) to work in this special case: with two uppercase strings $a and $b, it should return all the possible strings between $a and $b.
This could be used for example to get the excel column indexes.
e.g. <?php range('A','AD') ==> array('A','B','C',...,'Z','AA','AB','AC','AD') ?>
So I wrote the function getrange($min,$max) that exactly does this.
<?phpfunction getcolumnrange($min,$max){
$pointer=strtoupper($min);
$output=array();
while(positionalcomparison($pointer,strtoupper($max))<=0){
array_push($output,$pointer);
$pointer++;
}
return $output;
}
function
positionalcomparison($a,$b){
$a1=stringtointvalue($a); $b1=stringtointvalue($b);
if($a1>$b1)return 1;
else if($a1<$b1)return -1;
else return 0;
}function stringtointvalue($str){
$amount=0;
$strarra=array_reverse(str_split($str));
for(
$i=0;$i<strlen($str);$i++){
$amount+=(ord($strarra[$i])-64)*pow(26,$i);
}
return $amount;
}
?>
jazzduck AT gmail DOT com ¶
11 years ago
Despite the line above that says that the $step value should be "given as a positive number," the range() function will in fact correctly handle reversed (decrementing) ranges. For example:
<?php print_r( range( 24, 20 ) ); ?>
Array
(
[0] => 24
[1] => 23
[2] => 22
[3] => 21
[4] => 20
)
<?php print_r( range( 20, 11, -3 ) ); ?>
Array
(
[0] => 20
[1] => 17
[2] => 14
[3] => 11
)
It will actually ignore the sign of the $step argument, and determine whether to increment or decrement based purely on whether $start > $end or $end > $start. For example:
<?php print_r( range( 20, 11, 3 ) ); ?>
Array
(
[0] => 20
[1] => 17
[2] => 14
[3] => 11
)
<?php print_r( range( 11, 20, -3 ) ); ?>
Array
(
[0] => 11
[1] => 14
[2] => 17
[3] => 20
)
ThinkMedical at Gmail dot com ¶
16 years ago
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
for($i = $start; $i < $end; $i+=$step)
{
}foreach(range($start, $end, $step) as $i)
{
}
?>
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()).
chris at laflash dot org ¶
18 years ago
Quick HTML menus with minimum and maximum sets of years:
<?php
$year_built_min = 1900;
$year_built_max = date("Y");
?>
<select id="yearBuiltMin" size="1">
<?php 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 foreach (range($year_built_max, $year_built_min) as $year) { ?>
<option value="<?php echo($year); ?>"><?php echo($year); ?></option>
<?php } ?>
</select>
ccb_bc at hotmail dot com ¶
6 years ago
<?php
function natural_prime_numbers(array $range, bool $print_info = false) : array {
$start_time = time();
$primes_numbers = array();
$print = '';
$count_range = count($range);
foreach($range as $number){
$values_division_number = array();
if($number === 0 || $number === 1 || !is_int($number)){ continue;
}
if($number != 2 && $number%2 === 0){ continue;
}
for($i = 1; $i <= $number; $i++){
$resultado_divisao = $number / $i;
$values_division_number[$i] = $resultado_divisao;
if(
$count_range <= 20){ $print .= PHP_EOL;
$info = 'The number '.$number.' divided by the number '.$i.' is equal to: '.($number / $i);
$print .= $info;
if($i === $number){
$print .= PHP_EOL;
}
} array_walk($values_division_number, function($value, $index) use (&$values_division_number, &$number){ if(is_float($value) && $value != $number && $value > 1){
unset($values_division_number[$index]);
}
});$values_division_number = array_values($values_division_number); if(count($values_division_number) === 2 && $values_division_number[0] === $number && $values_division_number[1] === 1){
$primes_numbers[$number] = $number;
}
}
}
return array(
'length_prime_numbers' => count($primes_numbers),
'prime_numbers' => array_values($primes_numbers),
'print' => $print,
'total_time_processing' => (time() - $start_time).' seconds.',
);
}
var_dump(natural_prime_numbers(range(0, 11))); ?>
ktamas77 at gmail dot com ¶
13 years ago
if you need zero padding, string prefixes or any other masks, then a simple combination of array_map, inline functions and sprintf is your friend.
<?php
$a
= array_map(function($n) { return sprintf('sample_%03d', $n); }, range(50, 59) );print_r($a);?>
Will result:
Array
(
[0] => sample_050
[1] => sample_051
[2] => sample_052
[3] => sample_053
[4] => sample_054
[5] => sample_055
[6] => sample_056
[7] => sample_057
[8] => sample_058
[9] => sample_059
)
m0sh3 at hotmail dot com ¶
18 years ago
Here's how i use it to check if array is associative or not:
<?phpif (array_keys($arr)===range(0, sizeof($arr)-1)) {
} else {
}?>
Ray.Paseur often uses Gmail ¶
12 years ago
Interestingly, these two statements produce identical 26-character alphabet arrays.
<?php
$arr = range('A', 'Z');
$arr = range('AA', 'ZZ');
me at phpscott dot com ¶
13 years ago
So, I needed a quick and dirty way to create a dropdown select for hours, minutes and seconds using 2 digit formatting, and to create those arrays of data, I combined range with array merge..
<?php
$prepend = array('00','01','02','03','04','05','06','07','08','09');
$hours = array_merge($prepend,range(10, 23));
$minutes = array_merge($prepend,range(10, 59));
$seconds = $minutes;
?>
Super simple.
jay at NOspam dot myd3 dot com ¶
16 years ago
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)
{
$find[] = "/[^\d,\-]/";
$replace[] = "";$find[] = "/\-+/";
$replace[] = "-";$find[] = "/\,+/";
$replace[] = ",";$range_str = preg_replace($find, $replace, $range_str);$range_str = trim($range_str,",-");$range_out = array();
$ranges = explode(",", $range_str);
foreach(
$ranges as $range)
{
if(
is_numeric($range) || strlen($range) == 1)
{
$range_out[] = (int) $range;
}
else if(is_string($range))
{$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;
}
}$range = range_string("6, 3-1");?>
captvanhalen at gmail dot com ¶
17 years ago
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;
}
?>
dries at volta dot be ¶
13 years ago
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.
<?phpfunction createColumnsArray($end_column, $first_letters = '')
{
$columns = array();
$length = strlen($end_column);
$letters = range('A', 'Z');foreach ($letters as $letter) {
$column = $first_letters . $letter;$columns[] = $column;if ($column == $end_column)
return $columns;
}foreach ($columns as $column) {
if (!in_array($end_column, $columns) && strlen($column) < $length) {
$new_columns = createColumnsArray($end_column, $column);
$columns = array_merge($columns, $new_columns);
}
}
return
$columns;
}?>
Usage:
<?phpcreateColumnsArray('BI');?>
krdr dot mft at gmail dot com ¶
11 years ago
I've been introduced with range() function not so long ago, and I found that examples about it is somewhat wrong, even inefficient:
<?php
$o = "";
$time_start = microtime(true);
foreach(range(1, 10000) as $val) {
$o .= $val;
}
$time_end = microtime(true);
$time = $time_end - $time_start;
echo 'rangein: '.$time.'<br />'; $o = "";
$time_start = microtime(true);
$a = range(1, 10000);
foreach($a as $val) {
$o .= $val;
}
$time_end = microtime(true);
$time = $time_end - $time_start;
echo 'rangeout: '.$time.'<br />'; ?>
Which gives results:
rangein: 0.0025348663330078
rangeout: 0.0019199848175049
In some cases difference is even bigger and proportional to the range generated. I suppose that results of range() are cached/hashed.
Note: execution order does affects execution times, but difference still exists
qz ¶
9 years ago
If you're looking to fill an array to get a hash with 0-9 numerical values, using
range(0,9);
is a faster solution compared to
array_fill(0, 10, '');
18 years ago
<?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
)
VivienG ¶
1 year ago
They forgot to say something.
If the ending value not encounter the last sequence, the function return false.
In other words :
Given a int $n, if ( $start + $n * $step ) < $end and ( $start + ( $n + 1 ) * $step ) > $end, the function doen't give the maximum possible range, it returns a boolean.
So the last range number HAVE TO BE the end number.
3 years ago
You could use negative numbers in place of the `step` parameter. You need to make sure that the `start` is bigger than `end`. Note that range() function in php generates the range inclusive, i.e. it also includes the `end` parameter and not just up to it but not including it like most other languages.
The following snippet of code should explain what I mean about negative steps:
<?phpprint_r(range(100, 0, -10));?>
What happens basically is that the range function does not really care about what is bigger or smaller, it just adds the step to the start and appends that to the a temp result variable as long as it did not reach the end param value. In this case, adding negative numbers is like minus (computers do that for 2's complement under the hood.) This will cause the number to go from 100 to 90 and then the function will check if 90 reached 0 yet. Since it wouldn't have done that, it will keep adding -step (-10 in that case) to the latest result (i.e. 90) and so on and so forth.
Since range() is said to be better and faster than array_fill() I believe it was important for me to try it out and actually post this note on the official documentation just to make sure people can use this.
lsblsb at gmx dot de ¶
11 years ago
I needed a function, that creates a letter range with arbitrary length.
You specify via the $length parameter, how many entries you need.
Logic is analog to the logic of the column-titles in a calc-sheet.
<?phpfunction createLetterRange($length)
{
$range = array();
$letters = range('A', 'Z');
for($i=0; $i<$length; $i++)
{
$position = $i*26;
foreach($letters as $ii => $letter)
{
$position++;
if($position <= $length)
$range[] = ($position > 26 ? $range[$i-1] : '').$letter;
}
}
return $range;
}
?>
derek at php dot net ¶
20 years ago
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)) {
for ($i = (float)$low; $i*$sign <= $high*$sign; $i += $step*$sign)
$arr[] = $i;
} else {
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;
}
?>
pyetrosafe at gmail dot com ¶
11 years ago
To create a simple array or a multidimensional array with defined size and null values, use this expression:
<?php
$SimpleArray
= array_map(function($n) { return null; }, range(1, 3) );
$MultiArray = array_map(function($n) { return array_map(function($n) { return null; }, range(1, 2) ); }, range(1, 3) );var_dump($SimpleArray);
var_dump($MultiArray);?>
>>$SimpleArray
array(3) {
[0]=> NULL
[1]=> NULL
[2]=> NULL
}
>>$MultiArray
array(3) {
[0]=> array(2) {
[0]=> NULL
[1]=> NULL
}
[1]=> array(2) {
[0]=> NULL
[1]=> NULL
}
[2]=> array(2) {
[0]=> NULL
[1]=> NULL
}
}
?>
emory underscore smith at hotmail ¶
19 years ago
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
j dot gizmo at aon dot at ¶
20 years ago
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))
{
$step = ( abs($step)>0 ? abs($step) : 1 ); $dir = ($num1<=$num2 ? 1 : -1); for($i = (float)$num1; $i*$dir <= $num2*$dir; $i += $step*$dir)
{
$temp[] = $i;
}
}
else
{
$num1=ord((string)$num1); $num2=ord((string)$num2);
$step = ( abs($step)>0 ? abs($step) : 1 ); $dir = ($num1<=$num2 ? 1 : -1); for($i = $num1; $i*$dir <= $num2*$dir; $i += $step*$dir)
{
$temp[] = chr($i);
}
}
return $temp;
}print_r(myRange( 1, 3, 0.5 )); print_r(myRange( "a", "k", 3 )); print_r(myRange( "5", "9" )); print_r(myRange( "!", "%", 1/pi() )); ?>
unicod3 at hotmail dot com ¶
10 years ago
a function to get column index by letter
function getColumnNumber($char){
$alphabet = range('a','z');
$alphabet2 = range('a','z');
$newAlphabet = $alphabet;
foreach($alphabet as $k => $r)
{
foreach($alphabet2 as $row){
$newAlphabet[] = $r.$row;
}
}
$key = array_search($char, $newAlphabet);
return ($key !== false) ? $key : null;
}
Aram Kocharyan ¶
14 years ago
Here's a function to generate ranges from strings:
<?phpfunction range_str($str) {
preg_match('#(\\d+)\\s*-\\s*(\\d+)#', $str, $matches);
if ( count($matches) == 3 ) {
return range($matches[1], $matches[2]);
}
return FALSE;
}$array = range_str(' 2 - 4 ');
print_r($array);?>
This outputs:
Array
(
[0] => 2
[1] => 3
[2] => 4
)
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4