update
20240405 - viewSome追加 / forSome
viewSome
複数の配列を view できるメソッド
forSome
使い方 に記述
20240404 - 戻り値を格納する変数の変更 / unshift刷新 / methods追加 / init追加
array.ans を廃止、配列ごとに [VarName].ans を設定
更新したメソッド:pop / range / at / join
%ARRAY% array name 0 1 2 3 4 5
%ARRAY% at name 2
echo %name.ans%
unshift
上記更新のネックになっていた ので、記述を刷新
戻り値も廃止
methods
使えるメソッドの一覧表示
init
変数 ARRAY に call %~dpnx0
を代入
bat内で使用される変数 array.??? を初期化
20240318 - foreach
使い方 に、foreach について記述
array.bat に置きたかったけど断念
20240314 - shove追加 / at更新
shove は、pushの追加する要素数を一つだけにしたメソッドです
その分、array よりシンプルな処理です
rem at - 20240314
:_at
setlocal enabledelayedexpansion
set n=%~2
+ set m=%~3
if %n% lss 0 set /a n = !%~1.size! + %n%
+ if defined m set /a n += %m%
endlocal & call set array.ans=%%%~1.%n%%%
exit /b
rem %ARRAY% at [VarName] [Index] [incr]
%ARRAY% at var -3 -1
echo %array.ans%
[incr] の数値分 [Index] を増減させて取得
上記例では、-4 を指定したのと同じ
20240311 - pop追加 / range追加 / array修正
array内の変数名 __size を array.sizeに変更
%ARRAY% pop var
echo %array.ans%
説明不要のpop
shiftの追加予定は無し
rem range [VarName] [StartIndex] [EndIndex]
%ARRAY% range var -1 1
echo %array.ans%
[StartIndex]から[EndIndex]までの範囲をviewと同様に表示
array.ansにはjoinと同様の結果が格納
[StartIndex]の数値のほうが大きいと逆順になる
20240305 - unshift修正
rem unshift
:_unshift
setlocal enabledelayedexpansion
set joining=
- set el=%*
- set el=!el:*%~1 =!
- for %%i in (%el%) do (
+ for %%i in (%*) do (
set joining=!joining!,"%%~i"
)
- set joining=!joining:*,=!
+ set joining=!joining:*,"%~1",=!
call :_join %~1
endlocal & set array.ans=%joining%,%array.ans%
- set %~1.size=
+ set %~1.size=0
call :_array %~1 %array.ans%
exit /b
つぶやき
もう少し気軽に配列を扱えないものかと思い作ってみた
まだまだ、検証不足
想定は小規模な配列
遅延展開を意識せず配列を扱いたい人向け
array.batを通さず操作した時、sizeの更新がされないのが難点
array.bat
戻り値 は、変数 array.ans に格納
戻り値 は、変数 [VarName].ans に格納
本体
@echo off
call :_%*
exit /b
rem init
:_init
call :_delete array
set ARRAY=call %~dpnx0
exit /b
rem methods
:_methods
echo.
echo LIST of METHODS
echo.
echo init
echo methods
echo array [Var] [Args...]
echo shove [Var] [Arg]
echo unshift [Var] [Args...]
echo pop [Var]
echo at [Var] [Index [Increase]]
echo view [Var [rev]]
echo viewSome [Var [Var [Var...]]]
echo join [Var [rev]]
echo range [Var] [SartIndex [EndIndex]]
echo delete [Var]
echo.
echo [Var].ans
echo.
echo range joined string
echo join joined string
echo pop last element
echo at element of target index
echo.
exit /b
rem array
:_array
call set array.size=%%%~1.size%%
if "%array.size%" == "" (
set %~1=[[array]]
set %~1.size=0
)
set array.args=%*
call set array.args=%%array.args:*%~1 =%%
for %%i in (%array.args%) do (
call set %~1.%%%~1.size%%="%%~i"
set /a %~1.size += 1
)
set array.args=
set array.size=
exit /b
rem shove - 20240314
:_shove
call set array.size=%%%~1.size%%
if not defined array.size (
set %~1=[[array]]
set array.size=0
)
set %~1.%array.size%="%~2"
set /a %~1.size += 1
exit /b
rem unshift
:_unshift
set array.add=-1
for %%i in (%*) do set /a array.add += 1
if %array.add% equ 0 exit /b
call set array.from=%%%~1.size%%
if not defined array.from set %~1=[[array]]
set /a array.from -= 1
set /a array.to = %array.from% + %array.add%
set /a %~1.size = %array.to% + 1
:unshift.move
if %array.from% geq 0 (
call set %~1.%array.to%=%%%~1.%array.from%%%
set /a array.from -= 1
set /a array.to -= 1
goto :unshift.move
)
set array.idx=0
:unshift.add
if %array.add% gtr %array.idx% (
call set %~1.%array.idx%="%~2"
set /a array.idx += 1
shift /2
goto :unshift.add
)
exit /b
rem view
:_view
setlocal enabledelayedexpansion
if "%~2" == "rev" (
set /a start=!%~1.size! - 1
set incre=-1
set end=0
) else (
set start=0
set incre=1
set /a end=!%~1.size! - 1
)
for /l %%i in (%start%,%incre%,%end%) do (
echo %%i !%~1.%%i!
)
endlocal
exit /b
rem viewSome
:_viewSome
setlocal enabledelayedexpansion
set end=0
for %%i in (%*) do (
set size=!%%~i.size!
if !end! lss !size! set end=!size!
)
set /a end -= 1
for /l %%i in (0,1,%end%) do (
set row= %%i
for %%m in (%*) do (
set elm=!%%~m.%%i!
if not defined elm set elm=empty
set row=!row! !elm!
)
echo !row!
)
endlocal
exit /b
rem at - 20240314
:_at
setlocal enabledelayedexpansion
set n=%~2
set m=%~3
if %n% lss 0 set /a n = !%~1.size! + %n%
if defined m set /a n += %m%
endlocal & call set %~1.ans=%%%~1.%n%%%
exit /b
rem join
:_join
setlocal enabledelayedexpansion
if "%~2" == "rev" (
set /a start=!%~1.size! - 1
set incre=-1
set end=0
) else (
set start=0
set incre=1
set /a end=!%~1.size! - 1
)
set joining=
for /l %%i in (%start%,%incre%,%end%) do (
set joining=!joining!,!%~1.%%i!
)
set joining=!joining:*,=!
endlocal & set %~1.ans=%joining%
exit /b
rem delete
:_delete
set %~1=
for /f "usebackq delims== tokens=1" %%a in (`set %~1.`) do set %%a=
exit /b
rem pop - 20240311
:_pop
set /a %~1.size -= 1
setlocal enabledelayedexpansion
set n=!%~1.size!
endlocal & call set %~1.ans=%%%~1.%n%%%
call set %~1.%%%~1.size%%=
exit /b
rem range - 20240311
:_range
setlocal enabledelayedexpansion
set size=!%~1.size!
set start=%~2
set end=%~3
set incr=1
set joining=
if not defined start set start=0
if not defined end set /a end = %size% - 1
if %start% lss 0 set /a start += %size%
if %end% lss 0 set /a end += %size%
if %start% geq %size% set /a start = %size% - 1
if %end% geq %size% set /a end = %size% - 1
if %start% gtr %end% set incr=-1
for /l %%i in (%start%,%incr%,%end%) do (
echo %%i !%~1.%%i!
set joining=!joining!,!%~1.%%i!
)
set joining=!joining:*,=!
endlocal & set %~1.ans=%joining%
exit /b
使い方
準備
@echo off
set ARRAY=call %~dp0array.bat
rem %ARRAY% [Method] [VarName] [Args...]
array
配列を生成します
%ARRAY% array var "" a b c
set var
var=[[array]]
var.0=""
var.1="a"
var.2="b"
var.3="c"
var.size=4
このような変数が生成されます
配列が既に存在する時はpushします
%ARRAY% array var d e f ""
set var
var=[[array]]
var.0=""
var.1="a"
var.2="b"
var.3="c"
var.4="d"
var.5="e"
var.6="f"
var.7=""
var.size=8
unshift
前方に追加します
副産物として変数array.ansに
追加要素も含めjoinされた結果が格納されます
%ARRAY% unshift var 0 1 "" 2 3
set var
var=[[array]]
var.0="0"
var.1="1"
var.10="e"
var.11="f"
var.12=""
var.2=""
var.3="2"
var.4="3"
var.5=""
var.6="a"
var.7="b"
var.8="c"
var.9="d"
var.size=13
view
一覧表示します
indexとelementをTABで区切ってます
%ARRAY% view var
0 "0"
1 "1"
2 ""
3 "2"
4 "3"
5 ""
6 "a"
7 "b"
8 "c"
9 "d"
10 "e"
11 "f"
12 ""
VarNameの後にrevを付けると逆順に表示します
%ARRAY% view var rev
12 ""
11 "f"
10 "e"
9 "d"
8 "c"
7 "b"
6 "a"
5 ""
4 "3"
3 "2"
2 ""
1 "1"
0 "0"
viewSome
複数の配列を一覧表示します
要素が無い場合は empty 表示
rev は無し
%ARRAY% array var1 0 1
%ARRAY% array var2 2 3 4 5 6 7
%ARRAY% array var3 8
%ARRAY% array var4 9 0 a b c
%ARRAY% array var5 d e f g
%ARRAY% viewSome var1 var2 var3 var4 var5
0 "0" "2" "8" "9" "d"
1 "1" "3" empty "0" "e"
2 empty "4" empty "a" "f"
3 empty "5" empty "b" "g"
4 empty "6" empty "c" empty
5 empty "7" empty empty empty
at
指定したindexの要素を取得します
-1を指定すると末尾の要素を取得します
結果は変数 [VarName].ans に格納されます
update / [incr] の数値分 [Index] を増減させて取得
rem %ARRAY% at [VarName] [Index] [incr]
%ARRAY% at var -2
echo %var.ans%
%ARRAY% at var 1
echo %var.ans%
%ARRAY% at var -3 -1
echo %var.ans%
"f"
"1"
join
全ての要素を一つの文字列に連結します
区切り文字はカンマ固定です
結果は変数 [VarName].ans に格納されます
%ARRAY% join var
echo %var.ans%
"0","1","","2","3","","a","b","c","d","e","f",""
VarNameの後にrevを付けると逆順に連結します
%ARRAY% join var rev
echo %var.ans%
"","f","e","d","c","b","a","","3","2","","1","0"
delete
配列を削除します
%ARRAY% delete var
set var
環境変数 var が定義されていません
for-loop
%ARRAY% array var2 a b c d e f g
%ARRAY% join var2
echo # element
for %%i in (%var2.ans%) do (
echo # %%~i
)
echo # index element
for /f "usebackq delims= tokens=1,2" %%a in (`%ARRAY% view var2`) do (
echo # %%~a %%~b
)
foreach - 20240318
foreach と違うbatに呼び出したいサブルーチンがあるとエラーになるため、array.bat内ではなく、実装させたいbat内 に、サブルーチンとして記述する
set ARRAY=call %~dp0array.bat
%ARRAY% array var a b c d
rem call :foreach [VarName] [Label]
call :foreach var subroutine
echo %m_0% %m_1% %m_2% %m_3%
pause>nul
:subroutine
rem %1 : element
rem %2 : index
set m_%2=%1
exit /b
rem foreach
:foreach
call set /a array.size = %%%~1.size%% - 1
for /l %%i in (0,1,%array.size%) do (
call :%~2 %%%~1.%%i%% %%i
)
exit /b
forSome
foreach 同様、実行したいサブルーチンと同じbatに置く
ARRAY に call %~dp0array.bat
を代入していなければ書き換える
他のメソッドと違い、ラベル名を先に指定する
call :forSome test var1 var2 var3
set sum.
goto :end
:test
set /a sum.%~1 = %~2 + %~3 + %~4
exit /b
rem forSome [Label] [Var [Var [Var...]]]
:forSome
set array.args=%*
call set array.args=%%array.args:*%~1 =%%
for /f "usebackq delims= tokens=*" %%a in (`%ARRAY% viewSome %array.args%`) do call :%~1 %%~a
exit /b
:end
pause
get size
echo %var2.size%