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 
)
  • 2
    there's no delayed expansion in MS-DOS, only Windows cmd. DOS & cmd are completely different things although a few commands do work on both. Are the Command Prompt and MS-DOS the same thing? – phuclv Oct 11 '19 at 5:23
  • 1
    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!) – JosefZ Oct 11 '19 at 9:47
  • @JosefZ I'll give that a try and come back. – ejbytes Oct 11 '19 at 16:11
  • @phuclv I think I made a mental note of that when I learned some unix/linux stuff for college; UC was keen on using Linux for all lab work. Command line as it were. I come from the 90's loose talking of windows when all I did was watch someone fiddle with DOS as it was referred to. Some used to call it DOS prompt. It stuck with me, what can I say. And "aiint" aint a word.. but it is now, but aint always. – ejbytes Oct 11 '19 at 16:16
  • 1
    Do not add solutions to your question, post them as an answer instead! You may even accept your own answer then... – aschipfl Oct 14 '19 at 8:44
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.

| improve this answer | |
  • I was waiting for JosefX, from comment section. If I recall totally, it wasn't a matter of walking the array, but getting a loop to walk the array dynamically without knowing it's length; using "if defined", which works for dynamic purposes. Sort of like in C, next if not '/0'. I only submitted partial code. I was actually using the For /L for verification testing. I gave you an up vote. I think I started using single letter vars for counters, post 3 semesters of physics in college... my fave is 'i', but only for counters. – ejbytes Jan 2 at 8:49
  • Updated with a function for Getting the size of an Array. Because of the use of Single letter and Number variables in Batch Commands Like for loops, File Expansion, and Parameters, I refrain from Single digit Variables in Batch, and use _X instead – T3RR0R Jan 2 at 9:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.