Как расшириться, CMD окружают переменную дважды (рекурсивно)

Я не вижу что проблема с использованием стандарта для (;;) цикл. Немного теста

var x;
var a = [];
// filling array
var t0 = new Date().getTime();
for( var i = 0; i < 100000; i++ ) {
    a[i] = Math.floor( Math.random()*100000 );
}

// normal loop
var t1 = new Date().getTime();
for( var i = 0; i < 100000; i++ ) {
    x = a[i];
}

// using length
var t2 = new Date().getTime();
for( var i = 0; i < a.length; i++ ) {
    x = a[i];
}

// storing length (pollution - we now have a global l as well as an i )
var t3 = new Date().getTime();
for( var i = 0, l = a.length; i < l; i++ ) {
    x = a[i];
}

// for in
var t4 = new Date().getTime();
for( var i in a ) {
    x = a[i];
}

// checked for in
var t5 = new Date().getTime();
for( var i in a ) {
    if (a.hasOwnProperty(i)) {
        x = a[i];
    }
}

var t6 = new Date().getTime();
var msg = 'filling array: '+(t1-t0)+'ms\n'+
          'normal loop: '+(t2-t1)+'ms\n'+
          'using length: '+(t3-t2)+'ms\n'+
          'storing length: '+(t4-t3)+'ms\n'+
          'for in: '+(t5-t4)+'ms\n'+
          'checked for in: '+(t6-t5)+'ms';
console.log( msg );

результаты в:

filling array: 227ms
normal loop: 21ms
using length: 26ms
storing length: 24ms 
for in: 154ms
checked for in: 176ms

Так:-для взятия in самое длинное, с помощью свойства длины (то, которое является свойством и не должно быть вычислено), почти с такой скоростью, как хранит его сначала - который является только контактным усиком медленнее, чем использование целого числа.
И для () обычный способ циклично выполниться по массиву, который все ожидают и понимают.

Все они добавляют переменную к объему, который они выполняют в - я - который является общим названием для этого использования и так не должен использоваться для других вещей. Хранение длины сначала добавляет другой var - l - к объему, который является ненужный

12
задан Stephen Quan 21 August 2017 в 13:03
поделиться

4 ответа

Если думать в терминах менее сложного решения, это тоже дает CCC вы желаете.

setlocal enabledelayedexpansion
set AAA=BBB
set BBB=CCC
for /F  %%a in ('echo %AAA%') do  echo !%%a!

edit:

, чтобы проанализировать этот ответ:

setlocal enabledelayedexpansion - это позволит использовать любую настройку переменной среды во время вашей летучей мыши, как измененную во время процесса вашего для цикла .

установите AAA = BBB , установить BBB = CCC - совокупность данных установить операторы

для / F %% a in ('echo% AAA%') do echo! %% a! - Это указывает процессору выполнить цикл, хотя и только один раз, и извлечь первый возвращенный токен (разделитель пробела и табуляции по умолчанию) из выполнения команды в скобках и поместить его в переменную %% a (вне партии достаточно одного%). Если вы укажете эту переменную как %% a, вам нужно будет использовать %% a в вашем блоке do . Аналогично, если вы укажете %% i, используйте %% i в блоке do . Обратите внимание: чтобы переменная среды была разрешена в блоке do цикла for , вам нужно заключить ее в ! . (вам не нужно в блоке в , как я изначально писал - я внес это изменение в свое редактирование).

править:

Вы были очень близки со своим обновленным примером. Попробуйте это так:

@echo off
setlocal enabledelayedexpansion
set LIST=BBB CCC DDD
set BBB=111
set CCC=222
set DDD=333

for %%i in (%LIST%) do (
    for /F %%a in ('echo %%i') do echo !%%a!
)

Разница между вашим обновлением и этим заключается в том, что вы пытались повторить переменную среды в в , установленную с помощью in ('echo %%% i%') , но без ! для отложенного раскрытия заданных переменных. Если бы вы использовали в ('echo! %% i!') , вы бы увидели свои BBB , CCC и DDD переменные разрешены, но тогда блоку do вашего внутреннего цикла нечего будет разрешать - у вас нет переменных среды 111 . Имея это в виду, вы могли бы упростить свой цикл следующим образом:

@echo off
setlocal enabledelayedexpansion
set LIST=BBB CCC DDD
set BBB=111
set CCC=222
set DDD=333

for %%i in (%LIST%) do (echo !%%i!)
13
ответ дан 2 December 2019 в 05:28
поделиться

Двойная косвенная адресация (что очень удачно выразился pax ) напоминает разыменование указателя C.
Я сомневаюсь, что это поддерживается в командной оболочке Windows .

Считаете ли вы, что более крупная цель, на которую вы нацелены, может быть достигнута с помощью чего-то более простого;
может быть, меньший из подходов код-гольф , чем тот, который хорошо продуман pax ?

0
ответ дан 2 December 2019 в 05:28
поделиться

Следующий (мучительный) подход, кажется, работает нормально:

    @echo off
:main
    setlocal enableextensions enabledelayedexpansion
    set aaa=bbb
    set bbb=ccc
    call :myset x %%aaa%%
    echo %x%
    endlocal
    goto :eof
:myset
    for /F "usebackq tokens=*" %%i in (`echo %%%2%%`) do set %1=%%i
    goto :eof

Он выводит:

ccc

по желанию.

Я часто использовал этот трюк (например) для форматирования % aaa% в % x% до определенного размера (а-ля sprintf ), но это первый раз, когда мне пришлось выполнять двойную косвенную адресацию. Это работает, потому что вы не обнаружите, что лишний "%%" засасывается текущим уровнем оболочки.

3
ответ дан 2 December 2019 в 05:28
поделиться

Этот aaa.bat

@echo off
set aaa=bbb
set bbb=ccc
for /F %%i in ('echo %%%aaa%%%') do echo %%i

выводит

c:>ccc

В чем именно проблема?

3
ответ дан 2 December 2019 в 05:28
поделиться
Другие вопросы по тегам:

Похожие вопросы: