在使用 Windows 批处理文件中的 for 循环内索引来访问数组值时

huangapple go评论65阅读模式
英文:

Using an index inside a for loop to access an array value with Windows batch file

问题

Here are the translated parts of your code and output:

我有两个水果数组和相应的价格。我想在水果数组中搜索水果,并使用找到的索引来获取价格数组中的价格。

例1:
结果找到索引:3
找到的水果:Orange
价格:25

例2:
结果找到索引:4
找到的水果:Grapes
价格:15

例3:
结果找到索引:3
如何使用找到的索引显示找到的水果的价格?
结果找到索引:4
如何使用找到的索引显示找到的水果的价格?

关于价格的问题,您尝试了多种方法,但没有成功。以下是一种正确的方法来显示价格:

echo 价格方法:!prices[%%i]!

这应该会正确显示价格,例如:

价格方法:25
价格方法:15

希望这可以帮助您解决问题。如果您需要进一步的帮助,请告诉我。

英文:

I have two arrays of fruits and corresponding prices. I want to search for a fruit in the fruits array and use the found index to get the price using the prices array.

@echo off
setlocal enabledelayedexpansion

set "fruits[0]=6"
set "fruits[1]=Apple"
set "fruits[2]=Banana"
set "fruits[3]=Orange"
set "fruits[4]=Grapes"
set "fruits[5]=Mango"
set "fruits[6]=Pineapple"

set "prices[0]=6"
set "prices[1]=10"
set "prices[2]=30"
set "prices[3]=25"
set "prices[4]=15"
set "prices[5]=12"
set "prices[6]=16"

REM Example 1 works
call :SearchInArray "fruits" "Orange"
set /a i=result
echo Result found index: !i!
echo Fruit found: !fruits[%i%]!
echo Price: !prices[%i%]!

echo.

REM Example 2 works
call :SearchInArray "fruits" "Grapes"
set /a i=result
echo Result found index: !i!
echo Fruit found: !fruits[%i%]!
echo Price: !prices[%i%]!

echo.


REM Example 3 using a for loop does not!
set "searchValues=Orange Grapes"
for %%s in (%searchValues%) do (
  call :SearchInArray "fruits" "%%s"
  set /a i=!result!
  echo Result found index: !i!
  echo How to display here the price of the found fruit using the result found index?
)

exit /b

:SearchInArray
set "array=%~1"
set "searchString=%~2"
set "arrayLength=!%array%[0]!"

REM echo array=%array%
REM echo searchString=%searchString%
REM echo arrayLength=%arrayLength%

set "index=-1"
REM Loop through the array elements
for /L %%i in (1, 1, %arrayLength%) do (
  REM echo !%array%[%%i]!
  if "!%array%[%%i]!" == "%searchString%" (
    set "index=%%i"
    goto :ExitLoop
  )
)
:ExitLoop

REM Output the index of the string in the array
REM echo Index of "%searchString%" in the array: %index%
set "result=%index%"
exit /b

Output:

Example 1
Result found index: 3
Fruit found: Orange
Price: 25

Example 2
Result found index: 4
Fruit found: Grapes
Price: 15

Example 3
Result found index: 3
How to display the price of the found fruit using the result found index?
Result found index: 4
How to display the price of the found fruit using the result found index?

In first two examples it works as expected, but if I want to do it in a for loop using an string searchValues containing search strings it does find it but I struggle accessing the prices array using the found index. None works:

  echo Price method 1: prices[!i!]
  echo Price method 2: %prices[!i!]%
  echo Price method 3: !prices[!i!]!
  echo Price method 4: !!prices[!i!]!
  echo Price method 5: %prices[%i%]%
  echo Price method 6: !prices[%i%]!
  echo Price method 7: !!prices[%i%]!

Output:

Price:
Price: i
Price: i
Price: i
Price: 15
Price: 15
Price:
Price: i
Price: i
Price: i
Price: 15
Price: 15

It should be 15 for the first fruit Orange and 25 for the second fruit Grapes.

答案1

得分: 0

REM 示例 3
set "searchValues=橙子 葡萄"
for %%s in (%searchValues%) do (
  call :SearchInArray "水果" "%%s"
  set /a i=!result!
  echo 找到结果索引:!i!
  set "cmd=prices[!i!]"
  call echo 价格:%%!cmd!%%
  for /F %%A in ('echo %%!cmd!%%') do set "result=%%A"
  echo 结果:!result!
)
英文:
REM Example 3
set "searchValues=Orange Grapes"
for %%s in (%searchValues%) do (
  call :SearchInArray "fruits" "%%s"
  set /a i=!result!
  echo Result found index: !i!
  set "cmd=prices[!i!]"
  call echo Price: %%!cmd!%%
  for /F %%A in ('echo %%!cmd!%%') do set "result=%%A"
  echo Result: !result!
)

答案2

得分: 0

以下是您要翻译的内容:

答案是:

call echo Price: %%prices[!i!]%%

... 或者:

for %%i in (!i!) do echo Price: !prices[%%i%]!

... 如详细解释在这个答案

然而,我想向您展示一个 更简单 的方法来完成相同的事情。

与其定义 两个数组(一个包含水果,另一个包含价格),都带有 数值索引,不如定义一个具有水果作为索引的价格数组!这样,您可以直接通过 if defined price[%fruit%] 查询是否存在这样的水果,也可以直接获取其价格!这使整个过程变得更加简单:

@echo off
setlocal EnableDelayedExpansion

set "price[Apple]=10"
set "price[Banana]=30"
set "price[Orange]=25"
set "price[Grapes]=15"
set "price[Mango]=12"
set "price[Pineapple]=16"

REM 示例1
set "fruit=Orange"
if defined price[%fruit%] (
   echo 找到水果:%fruit%
   echo 价格:%price[%fruit%]%
) else (
   echo 未找到水果:%fruit%
)

REM 示例2与示例1相同

REM 使用FOR循环的示例3
set "searchValues=Orange Grapes"
for %%s in (%searchValues%) do (
   if defined price[%%s] (
      echo 找到水果:%%s
      echo 价格:%price[%%s]%
   ) else (
      echo 未找到水果:%%s
   )
)

如果要了解哪些水果已定义,只需执行以下操作:

for /F "tokens=2 delims=[]" %%a in ('set price[') do echo %%a

PS - 我建议您为数组使用单数(不带复数)的名称("price" 和 "fruit" 而不是 "prices" 和 "fruits")。

英文:

The answer to your question is:

call echo Price: %%prices[!i!]%%

... or:

for %%i in (!i!) do echo Price: !prices[%%i]!

... as explained with detail at this answer

However, I like to show you a much simpler method to do the same thing.

Instead of define two arrays (one with fruits and another one with prices), both with numeric indices, it is better to define just one array with prices that have the fruits as indices! In this way, you can directly question if such a fruit exist via if defined price[%fruit%] and also directly get its price! This makes the whole process much simpler:

@echo off
setlocal EnableDelayedExpansion

set "price[Apple]=10"
set "price[Banana]=30"
set "price[Orange]=25"
set "price[Grapes]=15"
set "price[Mango]=12"
set "price[Pineapple]=16"

REM Example 1
set "fruit=Orange"
if defined price[%fruit%] (
   echo Fruit found: %fruit%
   echo Price: !price[%fruit%]!
) else (
   echo Fruit NOT found: %fruit%
)

REM The example 2 is the same as 1

REM Example 3 using a FOR loop
set "searchValues=Orange Grapes"
for %%s in (%searchValues%) do (
   if defined price[%%s] (
      echo Fruit found: %%s
      echo Price: !price[%%s]!
   ) else (
      echo Fruit NOT found: %%s
   )
)

If you want to know which fruits are defined, just do this:

for /F "tokens=2 delims=[]" %%a in ('set price[') do echo %%a

PS - I suggest you to give singular (no plural) names to arrays ("price" and "fruit" instead of prices and fruits)

答案3

得分: 0

以类似于Aacini的答案的方式,您可以定义一个包含更多信息的结构。下面利用for metavariable修饰符~n来解析价格,并在=分隔符上限定varname=value以确定数量。

@Echo off

set "$Apple=1"
set "$Banana=2"
set "$Orange=3"
set "$Grapes=4"
set "$Mango=5"
set "$Pineapple=0"

:input
Set /p "item=选择水果: "
2>&1 > nul Set "$%item%" || (
	Echo(未找到水果
	Goto:input
)

For /f "tokens=1,2 delims==" %%G in ('Set $%Item%') Do Echo(水果: %Item% 价格: %%~nG 数量: %%H
Echo(重复 Y/N?
For /f "delims=" %%G in ('Choice /n /c:YN') Do if %%G==Y Goto:option

注意:我已经将"替换为正常的引号字符"

英文:

In a very similar manner to Aacini's answer, you can define a structure that contains more information still. The below takes advantage of the for metavariable modifer ~n to parse out the price, and delimits on the = seperator of varname=value to ascertain a quantity

@Echo off

set "$Apple=1"
set "$Banana=2"
set "$Orange=3"
set "$Grapes=4"
set "$Mango=5"
set "$Pineapple=0"

:input
Set /p "item=Choose a fruit: "
2>&1 > nul Set "$%item%" || (
	Echo(Fruit not found
	Goto:input
)

For /f "tokens=1,2 delims==" %%G in ('Set $%Item%')Do Echo(Fruit: %Item% Price:%%~nG Qty:%%H
Echo(Repeat Y/N?
For /f "delims=" %%G in ('Choice /n /c:YN')Do if %%G==Y Goto:option

答案4

得分: 0

以下是您请求的代码的翻译:

@Echo Off
SetLocal EnableExtensions DisableDelayedExpansion

For /F "Delims==" %%G In ('(Set fruits[ ^& Set prices[^) 2^>NUL^)') Do Set "%%G="

Set "fruits[0]=6"
Set "fruits[1]=Apple"
Set "fruits[2]=Banana"
Set "fruits[3]=Orange"
Set "fruits[4]=Grapes"
Set "fruits[5]=Mango"
Set "fruits[6]=Pineapple"

Set "prices[0]=6"
Set "prices[1]=10"
Set "prices[2]=30"
Set "prices[3]=25"
Set "prices[4]=15"
Set "prices[5]=12"
Set "prices[6]=16"

Set "searchValues=Orange Grapes"

SetLocal EnableDelayedExpansion

For /F "Tokens=2,* Delims=[]=" %%G In ('(Set fruits[^) ^| %SystemRoot%\System32\findstr.exe /RIC:"^fruits\[[123456789][0123456789]*\]=%searchValues: =$" /C:"^fruits\[[123456789][0123456789]*\]=%$"') Do Echo %%H 是索引 %%G,其价格为 !prices[%%G]!

Pause
EndLocal

请注意,我已经翻译了您提供的代码,并删除了不需要翻译的部分。如果您需要任何进一步的帮助,请随时告诉我。

英文:

Just for the sake of something completely different, and based upon your item values not containing spaces or other potentially problematic characters:

@Echo Off
SetLocal EnableExtensions DisableDelayedExpansion

For /F "Delims==" %%G In ('(Set fruits[ ^& Set prices[^) 2^>NUL') Do Set "%%G="

Set "fruits[0]=6"
Set "fruits[1]=Apple"
Set "fruits[2]=Banana"
Set "fruits[3]=Orange"
Set "fruits[4]=Grapes"
Set "fruits[5]=Mango"
Set "fruits[6]=Pineapple"

Set "prices[0]=6"
Set "prices[1]=10"
Set "prices[2]=30"
Set "prices[3]=25"
Set "prices[4]=15"
Set "prices[5]=12"
Set "prices[6]=16"

Set "searchValues=Orange Grapes"

SetLocal EnableDelayedExpansion

For /F "Tokens=2,* Delims=[]=" %%G In ('(Set fruits[^) ^| %SystemRoot%\System32\findstr.exe /RIC:"^fruits\[[123456789][0123456789]*\]=%searchValues: =$" /C:"^fruits\[[123456789][0123456789]*\]=%$"') Do Echo %%H is index %%G and its price is !prices[%%G]!

Pause
EndLocal

huangapple
  • 本文由 发表于 2023年6月8日 22:23:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/76432846.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定