[BATCH] Tipo de dato ARRAY en Batch

Iniciado por BatchianoISpyxolo, 24 Julio 2012, 14:08 PM

0 Miembros y 1 Visitante están viendo este tema.

BatchianoISpyxolo

Lo primero que debo decir es que, como ya sabéis, la estructura ARRAY no existe primitivamente en Batch, pero es simulado su tipo de dato (array unidimensional) a través de un conjunto de scripts que nos va a permitir manejar dicha estructura.

Si no conoces la estructura array visita:

Array data type: http://en.wikipedia.org/wiki/Array_data_type
Array data structure: http://en.wikipedia.org/wiki/Array_data_structure

Como dije antes, trabajaremos con arrays unidimensionales.

Para generar dicha estructura usaremos adicionalmente una función para crear strings.

create_string.bat
:: Standard Array Datatype Library V-0.5
:: [@FUNCTION NAME]: Create String
:: [@FUNCTION DESCRIPTION]: This script allows us to create strings and establishes some methods for them.
:: [@AUTHOR]: Manoel A. Folgueira
:: [@WEBSITE]: http://batchispano.com
:: [@Twitter]: @ant0nlg
:: create_string string_name:(bunch of chars, string) "text":(bunch of chars)

@echo off

set "text=%2"
for /f "usebackq tokens=*" %%i in ('!text!') do (
set "%1=%%~i"
)

:: String length method
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
)
)

set /a %1_limit=%1_len-1

goto :eof


A continuación, mostraré los scripts que nos permiten manejar la estructura. Los códigos se pueden mejorar (sort_array.bat optimizarlo a quicksort) y todavía se deben hacer algunos cambios a la estructura y quizás realizar una especificación para que no haya problemas a la hora de utilizarla. Finalmente veremos un ejemplo de como se comporta la estructura.

create_array.bat
:: Standard Array Datatype Library V-0.5
:: [@FUNCTION NAME]: Create Array
:: [@FUNCTION DESCRIPTION]: This peace of code will let you create an array from 0.
:: [@AUTHOR]: Manoel A. Folgueira
:: [@WEBSITE]: http://batchispano.com
:: [@Twitter]: @ant0nlg
:: create_array array_name:(bunch of chars, string) "delimiter":(char) "array_content":(string w/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
:: Standard Array Datatype Library V-0.5
:: [@FUNCTION NAME]: Show Array
:: [@FUNCTION DESCRIPTION]: The array structure of the array passed is shown.
:: [@AUTHOR]: Manoel A. Folgueira
:: [@WEBSITE]: http://batchispano.com
:: [@Twitter]: @ant0nlg
:: show_array array_name:(bunch of chars, 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
:: Standard Array Datatype Library V-0.5
:: [@FUNCTION NAME]: Insert Array
:: [@FUNCTION DESCRIPTION]: You can add any value you want to the specified array.
:: [@AUTHOR]: Manoel A. Folgueira
:: [@WEBSITE]: http://batchispano.com
:: [@Twitter]: @ant0nlg
:: insert_array array_name:(bunch of chars, string) "delimiter":(char) "value":(any) position:(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
:: Standard Array Datatype Library V-0.5
:: [@FUNCTION NAME]: Delete Array
:: [@FUNCTION DESCRIPTION]: With this function, you are able to delete any index of the array.
:: [@AUTHOR]: Manoel A. Folgueira
:: [@WEBSITE]: http://batchispano.com
:: [@Twitter]: @ant0nlg
:: delete_array array_name:(bunch of chars, string) "delimiter":(char) position:(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
:: Standard Array Datatype Library V-0.5
:: [@FUNCTION NAME]: Modify Array
:: [@FUNCTION DESCRIPTION]: It allows you to modify the content of any index within the array limits.
:: [@AUTHOR]: Manoel A. Folgueira
:: [@WEBSITE]: http://batchispano.com
:: [@Twitter]: @ant0nlg
:: modify_array array_name:(bunch of chars, string) "delimiter":(char) "value":(any) position:(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
:: Standard Array Datatype Library V-0.5
:: [@AUTHOR]: Manoel A. Folgueira
:: [@WEBSITE]: http://batchispano.com
:: [@Twitter]: @ant0nlg
:: sort_array array_name:(bunch of chars, string) "delimiter":(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
:: Standard Array Datatype Library V-0.5
:: [@FUNCTION NAME]: Linear Search
:: [@FUNCTION DESCRIPTION]: It allows you to find elements within an array without any restriction.
:: [@AUTHOR]: Manoel A. Folgueira
:: [@WEBSITE]: http://batchispano.com
:: [@Twitter]: @ant0nlg
:: l_search_array array_name:(bunch of chars, string) "value":(any) "position-to-return":(bunch of chars, string)

@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
:: Standard Array Datatype Library V-0.5
:: [@FUNCTION NAME]: Binary Search
:: [@FUNCTION DESCRIPTION]: It allows you to find elements within an array efectively. Array must be sorted.
:: [@AUTHOR]: Manoel A. Folgueira
:: [@WEBSITE]: http://batchispano.com
:: [@Twitter]: @ant0nlg
:: b_search_array array_name:(bunch of chars, string) "value":(any) "position-to-return":(bunch of chars, string)

@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.

script.bat
@echo off
setlocal enabledelayedexpansion

call create_array vector " " "50 -1 9"
call show_array vector
echo.
call insert_array vector " " "0" 1
call show_array vector
echo.
call delete_array vector " " 2
call show_array vector
echo.
call modify_array vector " " "-1" 1
call show_array vector
echo.
call l_search_array vector "50" LPos
echo Posicion de 50 con busqueda linear: !LPos!
echo.
call sort_array vector " "
echo Vector Ordenado
call show_array vector
echo.
call b_search_array vector "50" BPos
echo Posicion de 50 con busqueda binaria: !BPos!
echo.

pause

goto :eof




Y con esto me despido... Comentarios, críticas, insultos, y demás locuras que se les ocurran serán excelentemente bienvenidas...

Recuerden que todavía está por perfeccionar para el uso "común" de todos nosotros ;)

A mí, de momento, ya me ayudó a implementar el tipo SET o CONJUNTO :)


¡Saludos!
Puede que desees aprender a programar desde 0: www.espascal.es

Binary_Death

Muy bien  :P el asunto de los arrays en batch es interesante. Hay muchos intentos de implementaciones, la cuestión es que finalmente rara vez resultan útiles salvo en casos muy especiales.
Hace unos años yo también me puse a hacer un código del estilo, aunque en mi caso era para la gestión de una base de datos más fácilmente.

No sabía demasiado, pero bueh, aquí está el código: http://pastebin.com/0nyUVQ00

Por lo que veo te está quedando muy bien. Mi consejo es ese, que si quieres hacer el proyecto bien hecho, procura que sea deseable usarlos para programar ;)

BatchianoISpyxolo

Cita de: Binary_Death en 24 Julio 2012, 16:26 PM
Muy bien  :P el asunto de los arrays en batch es interesante. Hay muchos intentos de implementaciones, la cuestión es que finalmente rara vez resultan útiles salvo en casos muy especiales.
Hace unos años yo también me puse a hacer un código del estilo, aunque en mi caso era para la gestión de una base de datos más fácilmente.

No sabía demasiado, pero bueh, aquí está el código: http://pastebin.com/0nyUVQ00

Por lo que veo te está quedando muy bien. Mi consejo es ese, que si quieres hacer el proyecto bien hecho, procura que sea deseable usarlos para programar ;)

Sep. De todas formas se puede hacer un "include" de la "clase" tipo-array para tener toda la estructura en sólo un archivo.

Tiempo al tiempo xD

¡Saludetes!
Puede que desees aprender a programar desde 0: www.espascal.es

AgnesBlack

#3
muy bueno increible esta para crear un nuevo vector , desplazamiento y dems genial  ;-)
se merece un buen relajamiento un tema por los datos en bath
http://www.youtube.com/watch?v=VurhzANQ_B0

ahora me pondre a ver bien estos temas de vectores y matrices gracias :D