0

I would like to iterate through an array inside an other for loop.

I tried everything using ! % and %% and I can iterate i but cannot access my array using this i

here is the code that I would like to make it works :

rem stats.json contains -> { 1: "10%", 2: "20%", 3: "30%", 4: "40%", 5: "50%", 6: "60%" }
for /f "delims=" %%x in (stats.json) do set json=%%x
set json=%json:"=%
set "json=%json:~2,-2%"
set "json=%json:: =]=%"
set "stats[%json:, =" & set "stats[%"

echo stats[1]=%stats[1]%
echo stats[2]=%stats[2]%
echo stats[3]=%stats[3]%
echo stats[4]=%stats[4]%
echo stats[5]=%stats[5]%
echo stats[6]=%stats[6]%

set i=1
for %%f in (A, B, C) do (
 set /a j=!i!*2-1
 set /a k=!i!*2
 echo %%f - %stats[!j!]% - %stats[!k!]%
 set /a i+=1
)

anyone knows how to modifiy the for loop to make it works correctly?

j and k are correctly calculated but the line echo %%f - %stats[!j!]% - %stats[!k!]% does not work at all.

Current result :

A -  -
B -  -
C -  -

expecting result :

A - 10% - 20%
B - 30% - 40%
C - 50% - 60%
cz3ch
  • 409
  • 2
  • 11
  • Also, does your json actually have that single string, or are they newline seperated? – Gerhard Sep 05 '18 at 13:21
  • a) use [delayed expansion](https://stackoverflow.com/a/30284028/2152082 for `i`. b) use `set /a i+=1` to increment. c) you can't do math except with `set /a` (something like `stats[%i%*2-1]` definitively will not work) – Stephan Sep 05 '18 at 13:30
  • Inside your last `for ... do ( ... )` loop, you are going to need to use _delayed expansion_ (e.g. `setlocal enabledelayedexpansion` and use `!i!` to access variables. Also, you cannot do arithmetic in your "array" indexing. You also appear to be missing `%` around `stats`. – TripeHound Sep 05 '18 at 13:30
  • @Stephan SNAP!! – TripeHound Sep 05 '18 at 13:30
  • @gerhard-barnard I expect : A - 10% - 20% new line B - 30% - 40% new line C - 50% 60% – cz3ch Sep 05 '18 at 13:33
  • @gerhard-barnard the json got the string { 1: "10%", 2: "20%", 3: "30%", 4: "40%", 5: "50%", 6: "60%" } in a single line. the convertion of JSON into an array works well. the issue is to access the generated array unsing delay expansion – cz3ch Sep 05 '18 at 13:35
  • @stephan I made many tries using delay expansion and nothing worked, I used this code to show you what I expect – cz3ch Sep 05 '18 at 13:36
  • @tripehound @stephan I agree but accessing `%stats[!i!]%` inside the for loop doesn't work – cz3ch Sep 05 '18 at 13:40

2 Answers2

1

Here is the working code :

rem stats.json contains -> { 1: "10%", 2: "20%", 3: "30%", 4: "40%", 5: "50%", 6: "60%" }
for /f "delims=" %%x in (stats.json) do set json=%%x
set json=%json:"=%
set "json=%json:~2,-2%"
set "json=%json:: =]=%"
set "stats[%json:, =" & set "stats[%"

echo stats[1]=%stats[1]%
echo stats[2]=%stats[2]%
echo stats[3]=%stats[3]%
echo stats[4]=%stats[4]%
echo stats[5]=%stats[5]%
echo stats[6]=%stats[6]%

setlocal EnableDelayedExpansion
set /a i=1
for %%f in (A, B, C) do (
set /a j=!i!*2-1
set /a k=!i!*2
call echo(%%f - %%stats[!j!]%% - %%stats[!k!]%%
set /a i+=1
)
endlocal

I had to replace echo %%f - %stats[!j!]% - %stats[!k!]% by call echo(%%f - %%stats[!j!]%% - %%stats[!k!]%% but I don't know why : if someone got the answer

cz3ch
  • 409
  • 2
  • 11
  • I just came up with the very same solution - although I'm not sure, why it works this way. (btw: instead of all those `echo stats[...` statements, you can use just `set stats[`, which will list all variables starting with `stats[`) – Stephan Sep 05 '18 at 14:08
  • @stephan ok thank you. I admit that I am really curious on the reason why I should `call echo(` and double the `%` – cz3ch Sep 05 '18 at 19:09
  • I'm sure, the answer is [there](https://stackoverflow.com/a/4095133/2152082), but I still make savings for enough coffee to work my way through it... – Stephan Sep 05 '18 at 19:16
  • 1
    This type of management is fully explained at https://stackoverflow.com/questions/10166386/arrays-linked-lists-and-other-data-structures-in-cmd-exe-batch-script/10167990#10167990 – Aacini Sep 05 '18 at 21:31
1

This is the way I would do it:

@echo off
setlocal EnableDelayedExpansion

rem stats.json contains -> { 1: "10%", 2: "20%", 3: "30%", 4: "40%", 5: "50%", 6: "60%" }
for /f "delims=" %%x in (stats.json) do set "json=%%x"
set json=%json:"=%
set "json=%json:~2,-2%"
set "json=%json:: =]=%"
set "stats[%json:, =" & set "stats[%"

SET STATS

set /a i=1
for %%f in (A, B, C) do (
   set /a j=i*2-1, k=i*2
   for /F "tokens=1,2" %%j in ("!j! !k!") do echo %%f - !stats[%%j]! - !stats[%%k]!
   set /a i+=1
)

This code run much faster. For further details, see Arrays, linked lists and other data structures in cmd.exe (batch) script

Aacini
  • 65,180
  • 12
  • 72
  • 108
  • no it's wrong the `for /F "tokens=1,2" %%j in ("!j! !k!") do echo %%f - !stats[%%j]! - !stats[%%k]!` instruction is ways longer than two echo, the code is cool but this code runs much slower than the other. Try both with more variables and you'll see it on the console without any need to use a timer or something – cz3ch Sep 12 '18 at 16:10
  • 1
    _"this code runs much slower than the other... without any need to use a timer or something"_. Why not? Don't you like computer tests? **`:/`** I completed a simple timing test repeating the output part 1000 times. Your code takes 15.37 seconds, the mine 3.36 seconds; that is, it runs in 22% of the other or 4.57 times faster... – Aacini Sep 13 '18 at 17:21
  • 1
    Okay you are right, for 1000 iteration my solution takes 2.74 seconds and yours takes 0.218 second. so your solution takes only 7.95% of the time that mine takes so you are 12.57 time faster than I am – cz3ch Sep 20 '18 at 15:15