Arrays 批处理-从数组中删除元素

Arrays 批处理-从数组中删除元素,arrays,batch-file,Arrays,Batch File,我相信答案应该很简单。我从一个地方抓取一个目录列表,并将它们存储到一个文本文档中。然后我读取文本文档名称并将它们存储到一个数组中。在这个过程结束时,我希望删除数组中的所有条目 我之所以要这样做,是因为我将遍历几个文件夹位置,并将它们存储到同一个数组中。但是,当我每次都不清除数组时,当我稍后尝试打印它时,它似乎会给我带来各种各样的麻烦 每次填充下一个文件夹时,我都需要一个新数组 REM ********************************************************

我相信答案应该很简单。我从一个地方抓取一个目录列表,并将它们存储到一个文本文档中。然后我读取文本文档名称并将它们存储到一个数组中。在这个过程结束时,我希望删除数组中的所有条目

我之所以要这样做,是因为我将遍历几个文件夹位置,并将它们存储到同一个数组中。但是,当我每次都不清除数组时,当我稍后尝试打印它时,它似乎会给我带来各种各样的麻烦

每次填充下一个文件夹时,我都需要一个新数组

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

REM **************************************************************************  
这是我遇到的问题的一个例子。可以运行下面的代码来查看我所说的内容

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:D-H-S /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
罗霍先生给了我一个很好的解决这个问题的办法。这是它如何工作的一个例子

@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
@echo关闭
setlocal
设置“数组[0]=foo”
设置“数组[1]=bar”
设置“数组[2]=baz”
设置“数组[3]=qux”
设置“数组[4]=quux”
设置“数组[5]=corge”
回声。
回显首次打印输出
回显%array[0]、%array[1]、%array[2]、%array[3]、%array[4]、%array[5]%
暂停
rem//从元素3开始,删除2个元素并插入3个新元素
调用:拼接阵列3 2 grault garply waldo
回声。
回声第二次打印输出
回显%array[0]、%array[1]、%array[2]、%array[3]、%array[4]、%array[5]、%array[6]、%array[7]%
暂停
调用:拼接阵列0
REM集合数组[
雷姆后藤:EOF
回声。
回声第三打印输出
回显%array[0]、%array[1]、%array[2]、%array[3]、%array[4]、%array[5]、%array[6]%
暂停
设置“数组[0]=foo”
设置“数组[1]=bar”
设置“数组[2]=baz”
设置“数组[3]=qux”
设置“数组[4]=quux”
设置“数组[5]=corge”
回声。
回声第四打印输出
回显%array[0]、%array[1]、%array[2]、%array[3]、%array[4]、%array[5]、%array[6]%
暂停
:拼接[[…]]]
rem//的工作原理与JavaScript数组.prototype.splice()类似
雷姆//https://developer.mozilla.org/en-US/search?q=Array.prototype.splice()
延迟扩展
set/a idx=0,argskip=0,inserted=0,orig_ubound=-1

如果“%~3”==”(set/a“resume=1这是我上面评论的一个示例,演示了如何使用
setlocal
endlocal
来忘记变量

@echo关闭
setlocal
设置idx=0
rem//填充数组
延迟扩展
对于/f“delims=“%%I in('dir/b/a:-d')do(
设置“数组[!idx!]=%%~nxI”
设置/a idx+=1
)
rem//显示阵列
集合数组[
rem//销毁数组
端部
rem//结果
集合数组[
或者,如果您喜欢在数组元素中循环,而不是使用
set
来输出它们的值:

@echo关闭
setlocal
设置idx=0
rem//填充数组
延迟扩展
对于/f“delims=“%%I in('dir/b/a:-d')do(
设置“数组[!idx!]=%%~nxI”
set/a ubound=idx,idx+=1
)
rem//显示阵列
对于(0,1,%ubound%)中的/L%%I,请执行回显数组[%%I]:!数组[%%I]!
rem//销毁数组
端部
rem//结果
回显%1阵列[0]%

编辑:如果必须使用索引数组ish方法操作变量集合,我编写了一个与JavaScript类似的
:splice
函数。您可以使用该函数删除元素、插入元素、两者的组合,甚至可以根据需要清除整个数组。(只需调用:splice arrayname 0
即可取消设置数组中的所有元素。)

@echo关闭
setlocal
设置“数组[0]=foo”
设置“数组[1]=bar”
设置“数组[2]=baz”
设置“数组[3]=qux”
设置“数组[4]=quux”
设置“数组[5]=corge”
rem//从元素3开始,删除2个元素并插入3个新元素
调用:拼接阵列3 2 grault garply waldo
集合数组[
后藤:EOF
:拼接[[…]]]
rem//的工作原理与JavaScript数组.prototype.splice()类似
雷姆//https://developer.mozilla.org/en-US/search?q=Array.prototype.splice()
延迟扩展
set/a idx=0,argskip=0,inserted=0,orig_ubound=-1

如果“%~3”==”(set/a“resume=1也可以通过列表和索引变量模拟批处理中的数组,以将元素与索引值匹配

下面使用宏演示如何为列表类型阵列模拟:

  • 修改原始列表或将结果返回到克隆列表
  • 在提供的索引处拼接新元素
  • 按索引号提取特定元素
  • 从列表中删除元素
每个宏通过以下组合接受参数:

  • 子串修改

    • {e}
      替换为
      array
      varname和
      array clone/return
      varname
    • 接头宏的第二个参数是要插入的新值的索引
  • For循环If-else构造

    • 捕获要执行操作的索引号
使用宏和列表,而不是调用函数或将大量值赋值给相关变量,可以大大加快执行速度

拼接宏包括一种验证方法

@Echo关闭
rem/*宏定义-每个宏中必须有参数顺序*/
(设置\n=^^^
%=宏定义的换行变量。不修改=%
)
::用于宏的保留变量名:
:\n拼接提取删除组名插入前置附加Rvar RV cArr
:{i}{i#}代币
rem/*用法:%Splice:{e}={ListVarName}{Insertion Index}{可选的NewListVarname}%*/
如果%%n==2(%\n%
对于({e})中的/F“Tokens=1,2,3 Delims={}”%%1 Do(%\n%
设置“Groupname=%%1”%\n%
设置“{i}=%%2”%\n%
设置“cArr=%%3”%\n%
)%\n%
设置“Prepend=”%\n%
设置“Append=”%\n%
设置“{i}=0”%\n%
对于%%G in(!Groupname!)执行%%E in(!%%G!)执行(%\n%
如果!{i}!LSS!{i}!(%\n%
如果“!Prepend!”==”(设置“Prepend=%%E”)其他(设置“Prepend=!Prepend!%%E”)%\n%
)%\n%
如果!{i}!GEQ!{i}!(%\n%
如果“!Append!”==”(设置“Append=%%E”)其他(设置“Append=!Append!%%E”)%\n%
)%\n%
集合/A“{i}+=1”%\n%
)%\n%
如果不是“!cArr!”==”(设置