forked from PassingTheKnowledge/Batchography
-
Notifications
You must be signed in to change notification settings - Fork 0
/
array-1d-funcs.bat
308 lines (233 loc) · 6.28 KB
/
array-1d-funcs.bat
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
@echo off
::
:: The Batchography book by Elias Bachaalany
::
setlocal enabledelayedexpansion
:test-all
for %%a in (
test-create-with-size
test-find
test-delete
test-insert
test-love-story
) do (
echo --BEGIN %%a -------------------------------
call :%%a
echo --END %%a ---------------------------------
)
goto :eof
:: ==================================================================
:test-love-story
call :array-create A1
call :array-append A1 "elias" "peter" "mike"
echo The values are:
set A1[
call :array-insert A1 1 "mary"
echo The new values are:
set A1[
call :array-delete A1 2
echo The values after deletion:
set A1[
call :array-find A1 "mike"
if "%errorlevel%" equ "-1" (
echo Mike is hiding somewhere! Oh man!
) else (
call :array-delete A1 %errorlevel%
echo Mike's busted.
echo New values are now:
set A1[
)
call :array-destroy A1
echo The values after destruction are:
set A1[
goto :eof
:: ==================================================================
:test-find
call :array-create T1
call :array-append T1 1 2 6 12 0 44 99 44 912 6 2 5 1
echo The array's contents are:
set T1[
echo Finding items:
set needle=12
call :array-find T1 %needle%
echo Found "%needle%" at %errorlevel%
set needle=112
call :array-find T1 %needle%
echo Found "%needle%" at %errorlevel%
set needle=6
call :array-find T1 %needle%
echo Found "%needle%" at %errorlevel%
set /a p=%errorlevel%+1
call :array-find T1 %needle% %p%
echo Found next "%needle%" at %errorlevel%
goto :eof
:: ==================================================================
:test-create-with-size
call :array-create T1 5
set T1
goto :eof
:: ==================================================================
:test-delete
call :array-create T1
call :array-append T1 0 1 2 3
set T1[
echo Deleting...
call :array-delete T1 0
set T1[
goto :eof
:: ==================================================================
:test-insert
setlocal
:: ArrayLib
call :array-create ARR
call :array-append ARR 10 20
for /l %%a in (4, 1, 6) do (
set /a t=%%a*10
call :array-append ARR !t!
)
set ARR[
echo The array's length is: %ARR.length%
call :array-insert ARR 2 30
set ARR[
call :array-insert ARR 0 0
echo The array's length is: %ARR.length%
call :array-destroy ARR
set ARR[
echo ===
echo ===
call :array-create T1
call :array-append T1 0 1 3 4 5 7
call :array-insert T1 2 2
call :array-insert T1 6 6
call :array-insert T1 0 -1
set T1[
endlocal
goto :eof
:: ==================================================================
::
:: Create an empty array (or with the given size if specified)
::
:array-create <1=ArrayName> <2=size>
if defined %~1.length call :array-destroy %1
:: No size specified?
if "%~2" equ "" (
set %~1.length=0
) else (
:: Create an array with the size
set /a array_create_len=%~2-1
for /l %%a in (0, 1, !array_create_len!) do (
set %~1[%%a]=0
)
set %~1.length=%~2
set array_create_len=
)
goto :eof
:: ==================================================================
::
:: Destroy the array (and all its elements)
::
:array-destroy <1=ArrayName>
:: Compute the length
call set /a len=%%%~1.length%%%-1
:: Clear array values
for /L %%a in (0, 1, %len%) do (
set %~1[%%a]=
)
:: Clear the length attribute
set %~1.length=
goto :eof
:: ==================================================================
::
:: Append an element into the end of the array
::
:array-append <1=ArrayName> <2=Value>
:array-append-repeat
call set %~1[%%%~1.length%%]=%~2
set /A %~1.length+=1
shift /2
if "%~2" NEQ "" goto array-append-repeat
goto :eof
:: ==================================================================
::
:: Insert an element at a given position into the array
::
:array-insert <1=ArrayName> <2=Position> <3=Value>
call set array_insert_len=%%%~1.length%%
if %~2 GEQ %array_insert_len% (
echo Error: out of bounds!
exit /b -1
goto :eof
)
:: Shift items to the right
set /a array_insert_pa=%~2+1
for /L %%a in (%array_insert_len%, -1, %array_insert_pa%) do (
set /a array_insert_pa=%%a-1
call set %~1[%%a]=%%%~1[!array_insert_pa!]%%
)
:: Insert the new value
set %~1[%~2]=%~3
:: Increase the length
set /a %~1.length+=1
set array_insert_len=
set array_insert_pa=
goto :eof
:: ==================================================================
::
:: Delete an element from the array at a given position
::
:array-delete <1=ArrayName> <2=Position>
call set /a array_delete_len=%%%~1.length%%
if %~2 GEQ %array_delete_len% (
echo Error: out of bounds!
exit /b -1
goto :eof
)
set /a array_delete_len-=1
:: Shift items to the left
for /L %%a in (%~2, 1, %array_delete_len%) do (
set /a array_delete_pa=%%a+1
call set %~1[%%a]=%%%~1[!array_delete_pa!]%%
)
:: Purge the last element (since we shifted to the left)
set %~1[%array_delete_len%]=
:: Decrease the length
set /a %~1.length-=1
set array_delete_len=
set array_delete_pa=
goto :eof
:: ==================================================================
::
:: Find an element in the array and return the position
::
:array-find <1=ArrayName> <2=Value> <3=Start Pos> => <errorlevel=foundpos>
:: Set a default position if not set
set array_find_p=%~3
if not defined array_find_p set array_find_p=0
:: Get the length
call set /a array_find_len=%%%~1.length%%
:: Check the bounds of the start position
if %array_find_p% GEQ %array_find_len% (
echo Error: out of bounds!
exit /b -1
goto :eof
)
:: Search all items
set /a array_find_len-=1
for /L %%a in (%array_find_p%, 1, %array_find_len%) do (
call set array_find_len=%%%~1[%%a]%%
if "!array_find_len!" equ "%~2" (
set array_find_len=
set array_find_p=
exit /b %%a
)
)
set array_find_len=
set array_find_p=
exit /b -1
:: ==================================================================
::
:: Find an element in the array and return the position
::
:array-join <1=ArrayName> <2=Separator> => <3=Result>
:: Left as an exercise for the readers
goto :eof