LoginSignup
1
0

【bat】配列 array.bat

Last updated at Posted at 2024-03-04

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
変数 ARRAYcall %~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内の変数名 __sizearray.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 に格納

本体
array.bat
@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
result
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
result
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
result
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
result
	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
result
	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
result
        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%
result
"f"
"1"

join

全ての要素を一つの文字列に連結します
区切り文字はカンマ固定です
結果は変数 [VarName].ans に格納されます

%ARRAY% join var
echo %var.ans%
result
"0","1","","2","3","","a","b","c","d","e","f",""

VarNameの後にrevを付けると逆順に連結します

%ARRAY% join var rev
echo %var.ans%
result
"","f","e","d","c","b","a","","3","2","","1","0"

delete

配列を削除します

%ARRAY% delete var
set var
result
環境変数 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内 に、サブルーチンとして記述する

main.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に置く
ARRAYcall %~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%
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0