:GetIndexArray for when you need an array of indexes like "28,5-9,35,1,8"
Posted: 02 Oct 2023 03:13
This function works, but it' s not pretty
Quick example you call it like this
And it gives you an array like this
_myArrayOfIndex [0]:6
_myArrayOfIndex [1]:5
_myArrayOfIndex [2]:6
_myArrayOfIndex [3]:7
_myArrayOfIndex [4]:8
_myArrayOfIndex [5]:7
The syntax is
Call :GetIndexArray NameOfTheOutputArray Range1 Range2 RangeN
Where range can be a string value, a byref variable or a byref array
Each of these contains what I call "ranges"
Which consist of
individual numbers, like "28"
comma and space separated numbers "28,35,42" "28 35 42"
and actual ranges like you would defined printing pages "1-9" "35-27"
And you can combine these like "28,42,27-35,99,0,564,12-18-12,22-23-25-25-20"
and the like. Arrays can contain one of those on every of their elements
Current limitation is that I can' t handle negative numbers, this is why I consider this function unfinished, but already useful
Here the function as it currently exists
Here is the "Simple" DEMO code, note that this function will add to an existing output array
And here is the actual DEMO file
Not to be confused with :GetArrayIndex, a function that will returns the existing element index of an existing array !
This much simpler function works with simple arrays like
But would probably not work with more complex array of objects
like myobjectarray[28].collection[XX]
Here is the DEMO code
Here is the output of that
Quick example you call it like this
Code: Select all
Call :GetIndexArray _myArrayOfIndex "6,5-8,7"
_myArrayOfIndex [0]:6
_myArrayOfIndex [1]:5
_myArrayOfIndex [2]:6
_myArrayOfIndex [3]:7
_myArrayOfIndex [4]:8
_myArrayOfIndex [5]:7
The syntax is
Call :GetIndexArray NameOfTheOutputArray Range1 Range2 RangeN
Where range can be a string value, a byref variable or a byref array
Each of these contains what I call "ranges"
Which consist of
individual numbers, like "28"
comma and space separated numbers "28,35,42" "28 35 42"
and actual ranges like you would defined printing pages "1-9" "35-27"
And you can combine these like "28,42,27-35,99,0,564,12-18-12,22-23-25-25-20"
and the like. Arrays can contain one of those on every of their elements
Current limitation is that I can' t handle negative numbers, this is why I consider this function unfinished, but already useful
Here the function as it currently exists
Code: Select all
REM unfinished
::Usage Call :GetIndexArray OutputIndexArray ListOfIndex1 ListOfIndex2 ... ListOfIndexN
::Lists of index are appended to the OutputIndexArray, Lists of index can contain
::single elements "18"
::comma or space separated elements "10,14,23" "10 14 23"
::single ranges "2-9"
::multiple ranges "45-47,48-94" "45-47 48-94"
::ranges can be in descending order "33-66 66-33"
::ranges can includes more than two end stops "33-67-66-99"
::or a mix of all the above
::not implemented keywords like start middle quarter third twothird threequarter "start-45,middle-end,third-twothird,start-end,1-end"
::not implemented percentages 10% 20% 33% 100% "10%-20%,0%-100%,start-100%"
::not implemented features would require knowing the starting and ending index of the reference array
:GetIndexArray
set "_GetIndexArray_prefix=_GIA"
set "_GIA_output=%~1"
if "[%_GIA_output%]" EQU "[]" GoTo :EOF
if "[%_GIA_output%]" NEQ "[%_GIA_output:[]=%]" set "_GIA_output_suffix=%_GIA_output:*]=%" & set "_GIA_output=%_GIA_output:*[=%"
call set "_GIA_output_lbound=%%%~1.lbound%%"
call set "_GIA_output_ubound=%%%~1.ubound%%"
if "[%_GIA_output_lbound%]" EQU "[]" set /a "_GIA_output_lbound=0"
if "[%_GIA_output_ubound%]" EQU "[]" set /a "_GIA_output_ubound=%_GIA_output_lbound%-1"
shift
:GetIndexArray-arguments
if "[%~1]" EQU "[]" GoTo :EOF
Call :ClearVariablesByPrefix _GIA_current_list
set "_GIA_current_list=%~1"
set /a "_GIA_current_list_index=0"
for /f %%a in ('set %_GIA_current_list%[ 2^>nul') do GoTo :GetIndexArray-isarray-arguments
for %%a in (%_GIA_current_list:,= %) do ( call set "_GIA_current_list[%%_GIA_current_list_index%%]=%%a" & call set /a "_GIA_current_list_index+=1" )
set /a "_GIA_current_list_ubound=%_GIA_current_list_index%-1" & set /a "_GIA_current_list_index=0"
REM set _GIA_current_list
GoTo :GetIndexArray-loop
:GetIndexArray-isarray-arguments
call set /a "_GIA_current_list_array_index=%%%_GIA_current_list%.lbound%%" 2>nul
if not defined _GIA_current_list_array_index set /a "_GIA_current_list_array_index=0"
call set /a "_GIA_current_list_array_ubound=%%%_GIA_current_list%.ubound%%" 2>nul
:GetIndexArray-isarray-arguments-loop
call set _GIA_current_list_array_element=%%%_GIA_current_list%[%_GIA_current_list_array_index%]%%
for %%a in (%_GIA_current_list_array_element:,= %) do call set "_GIA_current_list[%%_GIA_current_list_index%%]=%%a" & call set /a "_GIA_current_list_index+=1"
set /a "_GIA_current_list_array_index+=1"
if %_GIA_current_list_array_index% LEQ %_GIA_current_list_array_ubound% GoTo :GetIndexArray-isarray-arguments-loop
set /a "_GIA_current_list_ubound=%_GIA_current_list_index%-1" & set /a "_GIA_current_list_index=0"
:GetIndexArray-loop
REM set _GIA_current_list
call set "_GIA_current_list_element=%%_GIA_current_list[%_GIA_current_list_index%]%%
if "[%_GIA_current_list_element%]" EQU "[%_GIA_current_list_element:-=%]" GoTo :GetIndexArray-range-skip
set /a "_GIA_current_list_element_index=0"
REM echo for %%a in (%_GIA_current_list_element:-= %)
for %%a in (%_GIA_current_list_element:-= %) do ( call set "_GIA_current_list_element[%%_GIA_current_list_element_index%%]=%%a" & call set /a "_GIA_current_list_element_index+=1" )
REM set _GIA_current_list_element
set /a "_GIA_current_list_element_ubound=%_GIA_current_list_element_index%-1" & set /a "_GIA_current_list_element_index=0"
call set /a "_GIA_current_list_element_start=%%_GIA_current_list_element[%_GIA_current_list_element_index%]%%
:GetIndexArray-range-loop
call set /a "_GIA_current_list_element_end=%%_GIA_current_list_element[%_GIA_current_list_element_index%]%%
if %_GIA_current_list_element_start% EQU %_GIA_current_list_element_end% ( call set /a "_GIA_output_ubound+=1" & call set "%_GIA_output%[%%_GIA_output_ubound%%]=%_GIA_current_list_element_start%" & GoTo :GetIndexArray-range-next)
REM if %_GIA_current_list_element_start% EQU %_GIA_current_list_element_end% echo TEST II %_GIA_current_list_element_start% II& GoTo :GetIndexArray-range-next
if %_GIA_current_list_element_start% GTR %_GIA_current_list_element_end% ( set "_GIA_current_list_element_direction=-" ) else ( set "_GIA_current_list_element_direction=+" )
set /a "_GIA_current_list_element_start%_GIA_current_list_element_direction%=1"
REM for /l %%a in (%_GIA_current_list_element_start%,%_GIA_current_list_element_direction%1,%_GIA_current_list_element_end%) do ( echo TEST II %%a II )
for /l %%a in (%_GIA_current_list_element_start%,%_GIA_current_list_element_direction%1,%_GIA_current_list_element_end%) do ( call set /a "_GIA_output_ubound+=1" & call set "%_GIA_output%[%%_GIA_output_ubound%%]=%%a" )
:GetIndexArray-range-next
set /a "_GIA_current_list_element_start=%_GIA_current_list_element_end%"
set /a "_GIA_current_list_element_index+=1"
if %_GIA_current_list_element_index% LEQ %_GIA_current_list_element_ubound% GoTo :GetIndexArray-range-loop
:GetIndexArray-range-skip
REM if "[%_GIA_current_list_element%]" EQU "[%_GIA_current_list_element:-=%]" echo TEST JJ %_GIA_current_list_element% JJ
if "[%_GIA_current_list_element%]" EQU "[%_GIA_current_list_element:-=%]" ( call set /a "_GIA_output_ubound+=1" & call set "%_GIA_output%[%%_GIA_output_ubound%%]=%_GIA_current_list_element%" )
:GetIndexArray-loop-end
Call :ClearVariablesByPrefix _GIA_current_list_element
set /a "_GIA_current_list_index+=1"
if %_GIA_current_list_index% LEQ %_GIA_current_list_ubound% GoTo :GetIndexArray-loop
shift
if "[%~1]" NEQ "[]" GoTo :GetIndexArray-arguments
set /a "%_GIA_output%.ubound=%_GIA_output_ubound%"
Call :ClearVariablesByPrefix %_GetIndexArray_prefix% _GetIndexArray
GoTo :EOF
Here is the "Simple" DEMO code, note that this function will add to an existing output array
Code: Select all
:GetIndexArray-simple-DEMO
echo.&echo test1
Call :GetIndexArray __GIADEMO_IndexArray "12"
Call :EchoArray __GIADEMO_IndexArray & Call :ClearVariablesByPrefix __GIADEMO
echo.&echo test2
Call :GetIndexArray __GIADEMO_IndexArray "12-18"
Call :EchoArray __GIADEMO_IndexArray & Call :ClearVariablesByPrefix __GIADEMO
echo.&echo test3
Call :GetIndexArray __GIADEMO_IndexArray "18-12"
Call :EchoArray __GIADEMO_IndexArray & Call :ClearVariablesByPrefix __GIADEMO
echo.&echo test4
Call :GetIndexArray __GIADEMO_IndexArray "6,18-12,7"
Call :EchoArray __GIADEMO_IndexArray & Call :ClearVariablesByPrefix __GIADEMO
echo.&echo test5
Call :GetIndexArray __GIADEMO_IndexArray "6,5-8,7"
Call :EchoArray __GIADEMO_IndexArray SHOWVARNAME
Call :EchoArray __GIADEMO_IndexArray & Call :ClearVariablesByPrefix __GIADEMO
echo.&echo test6
Call :GetIndexArray __GIADEMO_IndexArray "6,7,8,9" "1,2,3,4" "99,98-94,93" "123098,124187,12098124"
Call :EchoArray __GIADEMO_IndexArray & Call :ClearVariablesByPrefix __GIADEMO
echo.&echo test7
set __GIADEMO[0]=6,7
set __GIADEMO[1]=8
set __GIADEMO[2]=9-11
set __GIADEMO[3]=12498,12875,2,1-0
set __GIADEMO.ubound=3
Call :GetIndexArray __GIADEMO_IndexArray "6,7,8,9" __GIADEMO "1,2,3,4"
Call :EchoArray __GIADEMO_IndexArray & Call :ClearVariablesByPrefix __GIADEMO
echo.&echo test8
Call :GetIndexArray __GIADEMO_IndexArray "1,2,3"
Call :GetIndexArray __GIADEMO_IndexArray "4-6" "7"
Call :GetIndexArray __GIADEMO_IndexArray "8" "9-10" "00,11-14-15-15-15-15-20,39" "40"
Call :EchoArray __GIADEMO_IndexArray & Call :ClearVariablesByPrefix __GIADEMO
GoTo :EOF
Not to be confused with :GetArrayIndex, a function that will returns the existing element index of an existing array !
This much simpler function works with simple arrays like
Code: Select all
set mytestarray[1]=text1
set mytestarray[3]=text3
set mytestarray[4]=text4
set mytestarray[6]=text6
set mytestarray[12]=text12
set mytestarray[28]=text28
set mytestarray[2]=text2
like myobjectarray[28].collection[XX]
Code: Select all
::Usage Call :GetArrayIndex InputArray IndexArray
:GetArrayIndex
set "_GetArrayIndex_output=%~2"
call set "_GetArrayIndex_ubound=%%%~2.ubound%%"
if "[%_GetArrayIndex_ubound%]" EQU "[]" set /a "_GetArrayIndex_ubound=-1"
set /a "_GetArrayIndex_index=%_GetArrayIndex_ubound%"
for /f "tokens=1 delims==" %%a in ('set %~1[ 2^>nul') do for /f "tokens=2 delims=[]" %%b in ('set %%a 2^>nul') do call set /a "_GetArrayIndex_index+=1" & call set "%_GetArrayIndex_output%[%%_GetArrayIndex_index%%]=%%b"
set /a "%_GetArrayIndex_output%.ubound=%_GetArrayIndex_index%" & set "_GetArrayIndex_output=" & set "_GetArrayIndex_ubound=" & set "_GetArrayIndex_index="
GoTo :EOF
Code: Select all
:GetArrayIndex-DEMO
set mytestarray[1]=text1
set mytestarray[3]=text3
set mytestarray[4]=text4
set mytestarray[6]=text6
set mytestarray[12]=text12
set mytestarray[28]=text28
set mytestarray[2]=text2
echo This array mytestarray& echo.
set mytestarray
echo.& echo Contains the following indexes
Call :GetArrayIndex mytestarray myindexarray
Call :EchoArray myindexarray LINENUMBERS
GoTo :EOF
Here is the output of that
Code: Select all
GetArrayIndex.bat
This array mytestarray
mytestarray[12]=text12
mytestarray[1]=text1
mytestarray[28]=text28
mytestarray[2]=text2
mytestarray[3]=text3
mytestarray[4]=text4
mytestarray[6]=text6
Contains the following indexes
0:12
1:1
2:28
3:2
4:3
5:4
6:6