0

Oh the 10K and 20K and 100K will want to call this a duplicate.. but it's not.

The reason for this is merely:
Use Array Variable, "arr" Use a counting variable, "x", or whatever
Compare array index:
Does arr[0] == arr[1] ? (but with dynamic counting vars)
You can't do that with -- For /L (0,1, length), because set x+=1 and also the variable !arr! can't, or I don't know how, work together as both variables.
I've tried using %x% and !x! and setlocal and not using setlocal...

I can't seem to get the correct combination of variable syntax.
e.g.
!arr[%x%]!
!arr[!x!]!
%%arr[%x%]%%
etc.

In other words: arr[x] == arr[x+1] ? in a loop comparison

Set "inName=%~1"

Set arrCount=0
Set count=0
Set arr = []

:: Do some work
:: Some code delted for clarity of problem at hand
:: populate the arr (array)

:loop
call set "char=%%inName:~%count%,1%%"
If defined char (
    echo %count%[%char%]
    Set arr[%count%]=%char%
    Set /a arrCount+=1
    Set /a count+=1
    Set trimName=%trimName%%char%
    goto :loop
)
Set x=0

setlocal enableDelayedExpansion


REM fails of tried variable variations
::  echo array is %arrCount% in length
::  call echo X is %x% at %%arr[%x%]%%
::  call echo letter: %%arr[%x%]%% 
::  define: !arr[%x%]! !arr[!!x!!]! !!arr[!x!]!! and other variations

:SymLoop 
if defined !arr[%x%]! (
    echo X---: !arr[%x%]!
    CALL :increment RESULT x
    GOTO :SymLoop 
)
:: Different methods of resetting x to zero. Both fail

set /a x=0
CALL :reset_one RESULT x

:: For loop, using counter

for /L %%F in (0,1,%arrCount%) do (
    echo !arr[%%F]! and !arr[%x%]! vs !arr[!%x%!]!  -- x is !x!
    call Set /A x+=1
    REM CALL :increment RESULT x
)

endlocal

EXIT

:increment
    SET /A countArray+=1    SET /A x+=1


:reset_one  SET /A x=0

The input to this batch file is: some__name


Loops I've tried as you an see:
I have tried executing a simulated loop, via GOTO:SymLoop
Also, tried reading, echoing, array, via If defined !arr[%x%]!


RESULTS: I can get x to increment, but the combination of "arr" and "x" no

s and s vs 0  -- x is 0
o and s vs 0  -- x is 1
m and s vs 0  -- x is 2
e and s vs 0  -- x is 3
_ and s vs 0  -- x is 4
_ and s vs 0  -- x is 5
n and s vs 0  -- x is 6
a and s vs 0  -- x is 7
m and s vs 0  -- x is 8
e and s vs 0  -- x is 9
 and s vs 0  -- x is 10

The input: "some__name", will be compared with passing "some_name" into the batch file mybatch.bat >C:....>mybatch some__name



basically I populate the array [s][o][m]...
I want to ask: index 0 match index 1?
Later I will ask, is index-n of char "" and also index-n+1 of char "" ?


edit: I've come across a statement, comment, and found this. I'm not a Windows engineer. I use my skills as a programmer to get by in batch file creation. So I don't fully understand the deeper issues of my logic. From what I've read in the web "call echo" is a layer of expansion? So it works as if "setlocal enabledelaytedexpansion..." ? Somehow the second line "call echo" works, which leads me to believe that arr is indeed defined.

Set x=0
::fails
echo Array: arr[0] is %%arr[%x%]%%
::works 
Call echo Array: arr[0] is %%arr[%x%]%%

EDIT FIX
From Comment Suggestion:
if defined arr[%x%] ( could work. Read if /?: the correct syntax is IF DEFINED variable command (here variable is supposed to be a variable name and not expanded !variable!)




As for the rest of the code it was this above-comment that lead me to the full completion of the batch file. I was able to fix the :SymLoop and read the array correctly.

Partial code:

:SymLoop 
Call Set "ArrVar=%%arr[%x%]%%"
If defined ArrVar (
    Call echo X---: !arr[%x%]!
    Set /A x+=1
    GOTO :SymLoop 
)
ejbytes
  • 2,050

1 Answers1

1

* Update *

Function to determine Number of Elements in an Array:


Call :getsize ArrayName

:getsize
set _R=0
:countsize
IF NOT DEFINED %1[!_R!] (
        Set Max=!_R!
        ECHO Array contains !Max! Elements.
        GOTO :EOF
    ) else (
    Set /a _R+=1
    GOTO countsize
)

* Update: Paste Link demonstrating Shifting and Substitution of array Elements *

Can Be Found Here...

* Edit * To better cover the offset Comparison your Question entails:

REM - Function to be called.

:precomp
Set Check=0
Set /a Offset=!Check!-1
:comp
IF !X_Array[%Check%]!==!X_Array[%Offset%]! DO (
    Commands
    ) else (
    Commands
)

REM Increase in values placed after checks to allow for Array index 0
IF !check!==!ArraySize! GOTO :EOF
Set /a Check+=1
Set /a Offset+=1
Goto comp

Key points with defining and accessing arrays: In batch

-The variable you used to define an array Index cannot be used to Recall it. So !Array[%x%]! would only ever return the Last value set to x.

-Single Letter or number variables are generally Not recommended.

-For Loops can be used to Set values to the Index, and to retrieve / compare Arrays. -For loops are not Ideal for Shifting Values of Array Indexes. Use Function Loops for this.

-Count values do not need to be used for the array elements themselves, the For Variables can be instead.

An example of defining arrays with values that vary, and comparing them.

@REM this script is only to demonstrate the mechanics of Comparing Arrays and Shifting Arrays.

@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
Set Max=5
Set /p "Max=[Enter Array Range:]
REM - Account for Element 0:
Set /a Max-=1

:main
Set "Val=0"
cls

REM - Use for /L loop to assign values to array elements using Max as the total number of elements.

For /L %%a in (0,1,!Max!) DO (
                Set /p "Array[!Val!]=[Enter Array[!Val!] Value:]"
            If not defined Array[!Val!] (
            goto main
    )
    Set /a Val+=1
)

REM - Call function to display values assigned to array elements
CALL :Display
pause

REM - Tacks ann Element onto the end of the Array
REM - User inputs the New Elements Value.
REM - For Loop creats an Array for comparison
REM - The example Clones the Original Array and shifts the the Elements using a tmp offset Variable - !Val_O!
REM - CALLING and setting in function is vital to getting the value to set.

:append
Set /a Max+=1
cls
Set cvo=0
For /L %%a in (0,1,!Max!) DO (
        Set cva=%%a
        Call :Increment
        IF NOT DEFINED Array[!cvo!] (
        Set /p comp[%%a]=[Enter comp[%%a] Value:]
)
        IF !comp[%%a]!==!comp[%Max%]! (
        Set /p Array[!Max!]=[Enter Array[!Max!] Value:]
        Goto Comparison
    )
)

REM - For /L loop displays the values Assigned to each Element in the Comparison Array
:Comparison
CALL :Display
For /L %%a in (0,1,!Max!) DO (
            ECHO comp[%%a] = !comp[%%a]!
)

pause
cls

REM - For /L Loop Compares the Array and Substitutes Values If Arrays don't Match.
REM - Action taken is for Demonstration Purposes.
REM - the Action Demonstrated executes shifting the values of the Arrays Elements using the Clone/Offset Array.

:process
For /L %%a in (0,1,!Max!) DO (
            IF NOT !Array[%%a]!==!Comp[%%a]! (
        ECHO Array[%%a] !Array[%%a]! NEQ !Comp[%%a]! Comp[%%a]
        ECHO Values Exchanged for Array[%%a]
        Set "Array[%%a]=!comp[%%a]!"
    ) else (
    ECHO Values Matched for Array[%%a]
    )
)
pause

CALL :Display

:end
Pause
EXIT

:Increment
Set /a cvo+=1
Set comp[%cva%]=!Array[%cvo%]!
GOTO :EOF

GOTO :EOF

REM - Function that uses For /L loop to display the values of all currently assigned Elements.
:Display
cls
For /L %%a in (0,1,!Max!) DO (
            ECHO array[%%a] = !array[%%a]!
)
GOTO :EOF

* Regarding Your Question Of !Array[%X%]!==!Array[%X%+1]! *

It's never going to compare as Equal. You Need to Compare against a Second array / Value.

If you're aim is to Increment or * Shift the value * stored in the Array Element down / up by one, refer to the code linked in my paste at the top of the answer. It should contain enough examples to get you started.

T3RR0R
  • 621