I need to create an integer array that stops at a limit number and then goes on after another fixed value. Something like [1 2 3 4 5 10 11 12 13 14 15 16], where 5 is the limit number and 10 where it restarts.
Can you do something like set arr = [1:%lim%, 10:%max%]
?

- 123
- 7
3 Answers
@ECHO OFF
SETLOCAL
CALL :buildlist mylist 1 5 10 16
ECHO list is %mylist%
PAUSE
GOTO :eof
:: Produce a list of integers
:: %1 is listname
:: %2 is start value
:: %3 is end-value for range
:: %4 is restart-value
:: %5 is end-value
:buildlist
SET "%1="
FOR /L %%v IN (%2,1,%5) DO (
IF %%v leq %3 CALL SET "%1=%%%1%% %%v"
IF %%v geq %4 CALL SET "%1=%%%1%% %%v"
)
CALL SET "%1=%%%1:~1%%"
GOTO :eof
Batch really doesn't have arrays, but can simulate one with a little imagination.
The above routine produces a list of values to the specification, ready for processing by a for
statement.
Although it's possible to use delayedexpansion
, it's possible to avoid that facility. By CALL
ing a set
command, the command is parsed before execution so to decode the hieroglyphics, where %1
is the variable name "var"
SET "%1=%%%1%% %%v"
is processed as:
SET "var=%var% %v"
as %%
is an escaped-%, and %v
will be replaced by the value of the metavariable (loop-control variable) %%v
Similarly,
SET "%1=%%%1:~1%%"
is executed as
SET "var=%var:~1%"
which deletes the first character, which will be a space.

- 77,302
- 8
- 62
- 84
-
the funny thing is I already have a code with two loops for each set and I was trying to simplify it by putting everything in one set – alfred Jan 23 '22 at 18:03
-
Actually in your expansion explanation, `%%v` would also become processed as `%v`, because the `%`-escaping by doubling them is the actual reason for why they also have to be doubled at `for` meta-variables in batch files, and `for` itself only receives a singe `%`… – aschipfl Jan 24 '22 at 07:35
-
@aschipfl : quite so. I think I've fixed it - the issue is whether I've used the symbols in their original or sub-shell context. – Magoo Jan 24 '22 at 22:32
This problem is about several for /L
commands really, although it could be described in terms of nested if
commands or in other different ways...
There are several different methods to give the values of the for
commands, and also to implement they. I think this is the simplest one:
@echo off
setlocal EnableDelayedExpansion
set ranges="1:5" "10:16"
set "list="
for %%a in (%ranges::= 1 %) do for /L %%i in (%%~a) do set "list=!list! %%i"
echo list=%list%
Note that this method also works with several (more than two) ranges of values.
PS - This result is a list, not an array

- 65,180
- 12
- 72
- 108
-
Can you tell me in short what `%ranges::= 1 %` and `%%~a` do here ? I understand you set the limits in ranges and then "fill" them in the second loop, but i dont understand the syntax – alfred Jan 26 '22 at 20:22
-
@alfred: `%ranges::= 1 %` changes the colon by space-1-space, so it generates `"1 1 5" "10 1 16"`. In the first `for %%a` each _string in quotes_ is assigned to `%%a`. Then, `%%~a` is the same string without the quotes, so it first completes `for /L %%i in (1 1 5) do ...` and then `for /L %%i in (10 1 16) do ...`. In `for /L` command you can separate the 3 values by comma, semicolon, equal-sign or space. – Aacini Jan 26 '22 at 21:42
-
Batch doesn't have OR
operators, so you'll have to make do with two separate if
statements - one for the first set of numbers and one for the second set of numbers. You can, however, put both of those in the same for
loop:
@echo off
setlocal enabledelayedexpansion
set "lim=5"
set "max=10"
REM Setting counter to -1 because we're going to increment the counter and then
REM use it, and arrays famously start at zero.
set "counter=-1"
for /L %%A in (1,1,16) do (
if %%A LEQ %lim% (
set /a counter+=1
set "array[!counter!]=%%A"
)
if %%A GEQ %max% (
set /a counter+=1
set "array[!counter!]=%%A"
)
)
REM Display the contents of the array just to prove it worked.
REM Alphabetic order is used, so array[10] and array[11] are going to print before array[1]
set array[

- 13,229
- 5
- 50
- 55