Package - Removing Elements from an Array

I believe that the answer to this question should be quite simple. I take a list of directories from a place and save them in a text document. Then I read the names of text documents and save them in an array. At the end of this process, I would like all the entries from the array to be erased.

The reason I would like to do this is because I am going to go through several places in folders and store them in one array. However, when I do not clear the array every time, it seems to give me all kinds of features when I try to print it later along the line.

I need a fresh array every time I go to fill the next folder.

REM ************************************************************************** REM this part needs to delete the value but doesnt set !array[%arraywiper%]!=0 REM ************************************************************************** 

This is an example of the problem I am facing. The code below can be run to find out what I'm talking about.

 ECHO OFF & setLocal EnableDELAYedExpansion cls REM creates folder for text doc IF EXIST "c:\TEMP" (echo.) else (md c:\TEMP\) REM Scans C:\Program Files (x86) and stores into a text doc (for /f "delims=" %%a in ('dir /a:DHS /on /b "C:\Program Files (x86)"') do echo %%a)> c:\TEMP\dork_array_wipe.txt REM Counts the folders in the text doc for /d %%a in ("C:\Program Files (x86)\"*) do ( set /a locationcount+=1 ) REM Stores the values from the doc into an array for /F "usebackq delims=" %%a in ("c:\TEMP\dork_array_wipe.txt") do ( set /A i+=1 call set array[%%i%%]=%%a ) set arraywiper=1 :Arraywipeloop19 IF %arraywiper%==%locationcount% GOTO Arraywipecomplete19 else ( REM Prints array to show value entered array echo array (%arraywiper%): !array[%arraywiper%]! REM ************************************************************************** REM this part needs to delete the value but doesnt set !array[%arraywiper%]!=0 REM ************************************************************************** Set /a arraywiper+=1 REM Prints out array in question to veryify change took place echo array (%arraywiper%): !array[%arraywiper%]! GOTO Arraywipeloop19 ) :Arraywipecomplete19 pause 

Mr. Rojo gave me an excellent solution to this problem. This is an example of how this works.

 @echo off setlocal set "array[0]=foo" set "array[1]=bar" set "array[2]=baz" set "array[3]=qux" set "array[4]=quux" set "array[5]=corge" echo. echo first printout echo %array[0]%, %array[1]%, %array[2]%, %array[3]%, %array[4]%, %array[5]% pause rem // starting with element 3, delete 2 elements and insert 3 new call :splice array 3 2 grault garply waldo echo. echo second printout echo %array[0]%, %array[1]%, %array[2]%, %array[3]%, %array[4]%, %array[5]%, %array[6]%, %array[7]% pause call :splice array 0 REM set array[ REM goto :EOF echo. echo third printout echo %array[0]%, %array[1]%, %array[2]%, %array[3]%, %array[4]%, %array[5]%, %array[6]% pause set "array[0]=foo" set "array[1]=bar" set "array[2]=baz" set "array[3]=qux" set "array[4]=quux" set "array[5]=corge" echo. echo fourth printout echo %array[0]%, %array[1]%, %array[2]%, %array[3]%, %array[4]%, %array[5]%, %array[6]% pause :splice <array_name> <startIDX> [<deleteCount> [<item1> [<item2> [...]]]] rem // works like JavaScript Array.prototype.splice() rem // https://developer.mozilla.org/en-US/search?q=Array.prototype.splice() setlocal enabledelayedexpansion set /a idx = 0, argskip = 0, inserted = 0, orig_ubound = -1 if "%~3"=="" (set /a "resume = 1 << 30") else set /a resume = %~2 + %~3 for /f "tokens=1* delims==" %%I in ('set %~1[') do ( set /a orig_ubound += 1 if !idx! lss %~2 ( set "tmp[!idx!]=%%J" set /a ubound = idx, idx += 1 ) else ( if !inserted! equ 0 ( for %%# in (%*) do ( set /a argskip += 1, inserted = 1 if !argskip! gtr 3 ( set "tmp[!idx!]=%%~#" set /a ubound = idx, idx += 1, resume += 1 ) ) ) if !idx! geq !resume! ( set "tmp[!idx!]=%%J" set /a ubound = idx, idx += 1 ) else set /a resume -= 1 ) ) set "r=endlocal" for /f "tokens=1* delims=[" %%I in ('2^>NUL set tmp[') do ( set "r=!r!&set "%~1[%%J"" ) for /L %%I in (%idx%,1,%orig_ubound%) do set "r=!r!&set "%~1[%%I]="" %r%&exit/b 
+2
arrays batch-file
Feb 23 '16 at 20:54
source share
2 answers

Here is an illustration of what I commented above, demonstrating the use of setlocal and endlocal to forget variables.

 @echo off setlocal set idx=0 rem // populate array setlocal enabledelayedexpansion for /f "delims=" %%I in ('dir /b /a:-d') do ( set "array[!idx!]=%%~nxI" set /a idx += 1 ) rem // display array set array[ rem // destroy array endlocal rem // result set array[ 

Or, if you prefer to quote the elements of an array rather than using set to output your values:

 @echo off setlocal set idx=0 rem // populate array setlocal enabledelayedexpansion for /f "delims=" %%I in ('dir /b /a:-d') do ( set "array[!idx!]=%%~nxI" set /a ubound = idx, idx += 1 ) rem // display array for /L %%I in (0,1,%ubound%) do echo array[%%I]: !array[%%I]! rem // destroy array endlocal rem // result echo %array[0]% 



Edit: If you must manipulate a set of variables using the indexed array-ish methods, I wrote a function :splice , which works similar to JavaScript Array.prototype.splice() . You can use this to remove elements, insert elements, combine them, and even to clear the entire array if you want. (Just call :splice arrayname 0 to remove all elements from the array.)

 @echo off setlocal set "array[0]=foo" set "array[1]=bar" set "array[2]=baz" set "array[3]=qux" set "array[4]=quux" set "array[5]=corge" rem // starting with element 3, delete 2 elements and insert 3 new call :splice array 3 2 grault garply waldo set array[ goto :EOF :splice <array_name> <startIDX> [<deleteCount> [<item1> [<item2> [...]]]] rem // works like JavaScript Array.prototype.splice() rem // https://developer.mozilla.org/en-US/search?q=Array.prototype.splice() setlocal enabledelayedexpansion set /a idx = 0, argskip = 0, inserted = 0, orig_ubound = -1 if "%~3"=="" (set /a "resume = 1 << 30") else set /a resume = %~2 + %~3 for /f "tokens=1* delims==" %%I in ('set %~1[') do ( set /a orig_ubound += 1 if !idx! lss %~2 ( set "tmp[!idx!]=%%J" set /a ubound = idx, idx += 1 ) else ( if !inserted! equ 0 ( for %%# in (%*) do ( set /a argskip += 1, inserted = 1 if !argskip! gtr 3 ( set "tmp[!idx!]=%%~#" set /a ubound = idx, idx += 1, resume += 1 ) ) ) if !idx! geq !resume! ( set "tmp[!idx!]=%%J" set /a ubound = idx, idx += 1 ) else set /a resume -= 1 ) ) set "r=endlocal" for /f "tokens=1* delims=[" %%I in ('2^>NUL set tmp[') do ( set "r=!r!&set "%~1[%%J"" ) for /L %%I in (%idx%,1,%orig_ubound%) do set "r=!r!&set "%~1[%%I]="" %r%&exit/b 
+3
Feb 25 '16 at 16:22
source share

I cannot add a note, but I must mention the following supposed limitation of the above answer ...

When you use set array[ & endlocal remotely in the code from the line where the array was installed, it will probably also remove all others not related to the array variables set previously, unless endlocal is used in the called function, where the only variables are which belongs to the array. If this restriction is true, it should be mentioned in the answer.

This is worrying whether ENDLOCAL can be used universally around one code to remove only target variables, and if the above approach is common.

0
Jul 09 '16 at 14:35
source share



All Articles