Tipo de Dato Array Unidimensional en Batch Scripting
Tipo de Dato Array Unidimensional en Batch Scripting por [SOLO LOS USUARIOS REGISTRADOS PUEDEN VER LOS ENLACES. ]
Versión PDF: [SOLO LOS USUARIOS REGISTRADOS PUEDEN VER LOS ENLACES. ]
Conocimientos deseables (algunos necesarios):
Array data type: [SOLO LOS USUARIOS REGISTRADOS PUEDEN VER LOS ENLACES. ]
Array data structure: [SOLO LOS USUARIOS REGISTRADOS PUEDEN VER LOS ENLACES. ]
Esta aproximación trabaja sobre vectores (arrays en adelante) de una sola dimensión.
Por el momento 'thing' hace referencia a elementos que se puedan comparar con el operador LSS. Esta restricción desaparecerá en el futuro próximo.
Cito la documentación de IF
...
Si los comandos de extensión están habilitados, IF cambia así:
IF [/I] cadena1 op-de-comparación cadena2 comando
IF CMDEXTVERSION número comando
IF DEFINED variable comando
donde op-de-comparación puede ser:
EQU - igual
NEQ - no igual LSS - menor que
LEQ - menor que o igual
GTR - mayor que
GEQ - mayor que o igual
y el modificador /I, si se especifica, realiza comparaciones de cadena que
no distinguen entre mayúsculas y minúsculas. El modificador /I también puede
usarse en la forma cadena1==cadena2 de IF. Estas comparaciones son genéricas,
por lo que si tanto cadena1 como cadena2 se constituyen únicamente por dígitos
numéricos, entonces las cadenas se convierten a números y se realiza una
comparación numérica.
...
Para generar dicha estructura nos apoyaremos de una función para crear cadenas de texto (strings en adelante).
create_string.bat
Código:
:: [@FUNCTION NAME]: Create String
:: [@FUNCTION DESCRIPTION]: This script allows you to create unmodifable strings and establishes some properties for them.
:: [@AUTHOR]: pyxolo
:: create_string ( string_name: string, "string_content": double quoted string )
@echo off
set "text=%2"
for /f "usebackq tokens=*" %%i in ('!text!') do (
set "%1=%%~i"
)
:: String 'len' Property
set /a %1_len=0
if "!%1!" NEQ "" (
set /a i=0
set /a %1_len=0
:length_counter
if "!%1:~%i%,1!" NEQ "" (
set /a %1_len+=1
set /a i+=1
goto :length_counter
)
)
:: String 'limit' Property
set /a %1_limit=%1_len-1
goto :eof
Os muestro los scripts / funciones que nos permiten manejar la estructura. Las versiones de las funciones son mejorables y las iré mejorando en lo posible.
create_array.bat
Código:
:: [@FUNCTION NAME]: Create Array
:: [@FUNCTION DESCRIPTION]: This piece of code will let you create an array from scratch.
:: [@AUTHOR]: pyxolo:: [@WEBSITE]: http://batchispano.com
:: create_array ( array_name: string, "array_delimiter": double quoted char, "array_content": double quoted string :: elements separated by delimiter )
@echo off
if "%~3" NEQ "" (
call create_string del %2
call create_string content %3
call create_string %1 "[!content!]"
set /a content_l=!content_len! - 1
set /a offset=0
set /a index=0
for /l %%i in (0,1,!content_l!) do (
if "!content:~%%i,1!" EQU "!del!" (
set /a len=%%i-!offset!
call :set_value_index %1 !index! "content:~!offset!,!len!"
set /a offset=%%i+1
set /a index+=1
)
)
call :set_value_index %1 !index! "content:~!offset!,!content_len!"
set /a %1_limit=!index!
set /a %1_len=!index!+1
:: delete values
set del=
set content=
set content_l=
set offset=
set index=
set len=
)
goto :eof
:set_value_index
call create_string %1[%2] "!%~3!"
goto :eof
show_array.bat
Código:
:: [@FUNCTION NAME]: Show Array
:: [@FUNCTION DESCRIPTION]: The array structure of the array passed is shown. Mainly for debugging purposes.
:: [@AUTHOR]: pyxolo
:: show_array ( array_name: string )
@echo off
echo Vector: !%1!
for /l %%U in (0, 1, !%1_limit!) do (
echo %1[%%U] =^> !%1[%%U]!
)
goto :eof
insert_array.bat
Código:
:: [@FUNCTION NAME]: Insert Array
:: [@FUNCTION DESCRIPTION]: You can add any value you want to the specified array.
:: [@AUTHOR]: pyxolo
:: insert_array ( array_name: string, "delimiter": double quoted char, "value": double quoted thing, position: natural int )
@echo off
if %4 EQU !%1_len! (
set "%1[%4]=%~3"
set "%1="
set /a %1_len+=1
set /a %1_limit+=1
for /l %%i in (0, 1, !%1_limit!) do (
set "%1=!%1!%~2!%1[%%i]!"
)
set %1=[!%1:~1!]
) else if %4 LSS !%1_len! (
if %4 GEQ 0 (
set /a %1_len+=1
set /a %1_limit+=1
set /a limit=%4+1
for /l %%j in (!%1_limit!, -1, !limit!) do (
set /a bPos=%%j-1
call :set_value %1[%%j] "%1[!bPos!]"
)
call create_string %1[%4] "%~3"
set "%1="
for /l %%k in (0, 1, !%1_limit!) do (
set "%1=!%1!%~2!%1[%%k]!"
)
set %1=[!%1:~1!]
)
)
goto :eof
:set_value
call create_string %1 "!%~2!"
goto :eof
delete_array.bat
Código:
:: [@FUNCTION NAME]: Delete Array
:: [@FUNCTION DESCRIPTION]: With this function, you are able to delete any indexed value of the array.
:: [@AUTHOR]: pyxolo
:: delete_array ( array_name: string, "delimiter": double quoted char, position: natural int )
@echo off
if !%1_len! EQU 1 (
set /a %1_len-=1
set /a %1_limit-=1
call create_string %1[0] ""
set "%1=[]"
) else (
if %3 EQU !%1_limit! (
set "%1[%3]="
set "%1="
set /a %1_len-=1
set /a %1_limit-=1
for /l %%i in (0, 1, !%1_limit!) do (
set "%1=!%1!%~2!%1[%%i]!"
)
set %1=[!%1:~1!]
) else if %3 LSS !%1_len! (
if %3 GEQ 0 (
set /a %1_len-=1
set /a %1_limit-=1
for /l %%j in (%3, 1, !%1_limit!) do (
set /a bPos=%%j+1
call :set_value %1[%%j] "%1[!bPos!]"
)
call create_string %1[!%1_len!] ""
set "%1="
for /l %%k in (0, 1, !%1_limit!) do (
set "%1=!%1!%~2!%1[%%k]!"
)
set %1=[!%1:~1!]
)
)
)
goto :eof
:set_value
call create_string %1 "!%~2!"
goto :eof
modify_array.bat
Código:
:: [@FUNCTION NAME]: Modify Array
:: [@FUNCTION DESCRIPTION]: It allows you to modify the content of any index within the array limits.
:: [@AUTHOR]: pyxolo
:: modify_array ( array_name: string, "delimiter": double quoted char, "value": double quoted thing, position: natural int )
@echo off
if %4 geq 0 (
if %4 leq !%1_limit! (
call create_string %1[%4] "%~3"
set "%1="
for /l %%i in (0, 1, !%1_limit!) do (
set "%1=!%1!%~2!%1[%%i]!"
)
set "%1=[!%1:~1!]"
)
)
goto :eof
sort_array.bat
Código:
:: [@FUNCTION NAME]: Sort Array
:: [@FUNCTION DESCRIPTION]: This function sorts an array for you. Bubble sort is yet implemented.
:: This is going to be replaced by some quicksort method probably.
:: Time tests are going to be performed on different algorithms (quicksort, mergesort, heapsort...)
:: and the best approach will remain with this method name (alias).
:: This is, 'sort_array' function name will be an alias to the best performing method in different situations.
:: Any other implementations will receive their own name.
:: [@AUTHOR]: pyxolo
:: sort_array ( array_name: string "delimiter": double quoted char )
@echo off
call create_string array "%~1"
if !%array%_len! gtr 0 (
for /l %%i in (0, 1, !%array%_limit!) do (
for /l %%j in (%%i, 1, !%array%_limit!) do (
if !%array%[%%j]! lss !%array%[%%i]! (
call create_string t "!%array%[%%i]!"
call create_string %array%[%%i] "!%array%[%%j]!"
call create_string %array%[%%j] "!t!"
)
)
)
set "%array%="
for /l %%k in (0, 1, !%array%_limit!) do (
set "%array%=!%array%!%~2!%array%[%%k]!"
)
if !%array%_len! EQU 1 (
set %array%=[!%array%!]
) else (
set "%array%=[!%array%:~1!]"
)
)
goto :eof
l_search_array.bat
Código:
:: [@FUNCTION NAME]: Linear Search
:: [@FUNCTION DESCRIPTION]: It allows you to find elements within an array without any restriction. Linear search is performed.
:: [@AUTHOR]: pyxolo
:: l_search_array ( array_name: string, "value": double quoted thing, pos_var_name: string :: variable name for the position returned )
@echo off
set /a %~3=-1
set /a index=0
:search_loop
if %~2 EQU !%1[%index%]! (
set /a %~3=!index!
goto :eof
)
if !index! gtr !%1_limit! (goto :eof)
set /a index+=1
goto :search_loop
goto :eof
b_search_array.bat
Código:
:: [@FUNCTION NAME]: Binary Search
:: [@FUNCTION DESCRIPTION]: It allows you to find elements within an array effectively (binary search). Array must be sorted.
:: [@AUTHOR]: pyxolo
:: b_search_array ( array_name: string, "value": double quoted thing, pos_var_name: string :: variable name for the position returned )
@echo off
set /a %~3=-1
set /a LowerLimit=0
set /a HigherLimit=!%1_limit!
:search_loop
set /a CentralLimit=(LowerLimit+HigherLimit)/2
if %~2 EQU !%1[%CentralLimit%]! (
set /a %~3=!CentralLimit!
) else if %~2 gtr !%1[%CentralLimit%]! (
set /a LowerLimit=CentralLimit+1
) else (
set /a HigherLimit=CentralLimit-1
)
if !LowerLimit! gtr !HigherLimit! (
set "LowerLimit="
set "HigherLimit="
set "CentralLimit="
goto :eof
) else if !%~3! NEQ -1 (
set "LowerLimit="
set "HigherLimit="
set "CentralLimit="
goto :eof
) else (
goto :search_loop
)
goto :eof
Como se puede apreciar, en ningún script se habilita la expansión de variables, por lo que deberemos habilitarla en nuestros scripts.
Aquí un ejemplo de cómo funciona la estructura array hasta el momento.