Compare array of numbers in a batch script

Viewed 361

I'm trying to compare a sequence of 9 numbers (separated by ,) using a batch file. The comparison is always made by the corresponding sequence like:

mPrevious[0] <-> mCurrent[0]
mPrevious[1] <-> mCurrent[1]

I need to know if at least one sequece have changed. In the example bellow, 234 changed to 230 and 146 to 149.

The sketch I have so far is:

setlocal ENABLEDELAYEDEXPANSION
@echo off

set mPrevious=229,234,235,127,58,0,131,133,146
set mCurrent=229,230,235,127,58,0,131,133,149

for /f "tokens=1,2,3,4,5,6,7,8,9 delims=," %%a IN ('echo !mPrevious!') do (

)

The number of entries (currently 9) might change in the future. But for now they are just 9.

I'm not sure what is the proper way to do it inside a batch script.

3 Answers
@echo off 

title <nul && title ...\%~nx0
setlocal enabledelayedexpansion

set "_mPrevious=229,234,235,127,58,0,131,133,146"
set "_mCurrents=229,230,235,127,58,0,131,133,149"

echo/!_mPrevious!|find "!_mCurrents!" >nul && (
   endlocal & echo\Nothing changed^!! & goto :EOF )

for %%i in (!_mPrevious!)do set /a "_i+=1+0" && call set "_mPrev_!_i!=%%~i"
for %%j in (!_mCurrents!)do set /a "_j+=1+0" && call set "_mCurr_!_j!=%%~j"

if !_i! neq !_j! endlocal & echo\Varyables have different lengths^!! & goto :EOF

for /L %%L in (1 1 !_j!)do if !_mPrev_%%~L! neq !_mCurr_%%~L! echo\!_mPrev_%%~L! updated to: !_mCurr_%%~L!

endlocal && goto :EOF
  • Outputs:
234 updated to: 230
146 updated to: 149

One simple way to do this only if necessary and only if both variable has same length:

Make a first comparison if the variables are the same, there was a change in the values:

echo/!_mPrevious!|find "!_mCurrents!" >nul && (
   endlocal & echo\Nothing changed^!! & goto :EOF )

And a second if they continue with the same length:

if !_i! neq !_j! endlocal & echo\Variables have different lengths^!! & goto :EOF

Obs.: 1. I prefer replace [ ] to one simple _

Obs.: 2. Also, change i+= to _i+=1+0, where no need predefined set command: set i=0

The FOR token delimiters are: <SPACE> <TAB> <NBSP> , ; =
Therefore, you can put it into a FOR loop, but it would fail if the content contained * or ?.

@echo off
====SETLOCAL EnableDelayedExpansion EnableExtensions
set/a"#=cnt=0"


::Define lists
set "mPrevious=229,234,235,127,58,0,131,133,146"
set  "mCurrent=229,230,235,127,58,0,131,133,149"


FOR %%P in (!mPrevious!) do (
    FOR %%C in (!mCurrent!) do (
        if !cnt! equ !#! echo(%%P %%C
        set/a"cnt+=1"
    )
    set/a"cnt=0,#+=1"
)

This is an approach using some self-expanding code:

@echo off
setlocal EnableDelayedExpansion

rem // Define constants here:
set "mPrevious=229,234,235,127,58,0,131,133,146"
set "mCurrents=229,230,235,127,58,0,131,133,149"

rem // Initialise auxiliary variables and indexes:
set "nPrevious=,%mPrevious%" & set /A "i=0"
set "nCurrents=,%mCurrents%" & set /A "j=0"

rem // Convert lists to arrays using self-expanding code:
set "_=%nPrevious:,=" & set /A "i+=1" & set "nPrevious[!i!]=%"
set "_=%nCurrents:,=" & set /A "j+=1" & set "nCurrents[!j!]=%"

rem // Verify availability of arrays:
> nul 2>&1 set nPrevious[ || set /A "i=0"
> nul 2>&1 set nCurrents[ || set /A "j=0"

rem // Determine minimal and maximal count:
if %j% gtr %i% (set /A "k=i, l=j" & set "_=#") else (set /A "k=j, l=i" & set "_=")

rem // Compare corresponding elements:
for /L %%K in (1,1,%k%) do if !nPrevious[%%K]! neq !nCurrents[%%K]! (
    echo [%%K]: !nPrevious[%%K]!    -^> !nCurrents[%%K]!
)

rem // Return removed or added elements:
set /A "k+=1" & for /L %%K in (!k!,1,%l%) do if defined _ (
    echo [%%K]: --- -^> !nCurrents[%%K]!
) else (
    echo [%%K]: !nPrevious[%%K]!    -^> ---
)

endlocal

Sample output, relying on the data of the question:

[2]:    234     ->      230
[9]:    146     ->      149
Related