Я хотел бы что-то вроде этого:
each[i_, {1,2,3},
Print[i]
]
Или, в более общем смысле, чтобы деструктурировать произвольные вещи в списке, который вы зацикливаете, например:
each[{i_, j_}, {{1,10}, {2,20}, {3,30}},
Print[i*j]
]
Обычно вы хотите использовать Map
или другие чисто функциональные конструкции и избегать нефункционального стиля программирования, в котором вы используете побочные эффекты. Но вот пример, где я думаю, что конструкция for-each в высшей степени полезна:
Скажем, у меня есть список опций (правил), которые соединяют символы с выражениями, например
attrVals = {a -> 7, b -> 8, c -> 9}
Теперь я хочу создать хеш-таблицу, где я делаю очевидное сопоставление этих символов с этими числами. Я не думаю, что есть более чистый способ сделать это, чем
each[a_ -> v_, attrVals, h[a] = v]
Дополнительные тестовые случаи
В этом примере мы преобразуем список переменных:
a = 1;
b = 2;
c = 3;
each[i_, {a,b,c}, i = f[i]]
После вышеизложенного {a,b,c}
должно оцениваться как {f[1],f[2],f[3]}
. Обратите внимание, что это означает, что второй аргумент each
должен оставаться невычисленным, если это список.
Если невычисленная форма не является списком, она должна оценивать второй аргумент. Например:
each[i_, Rest[{a,b,c}], Print[i]]
Это должно напечатать значения b
и c
.
Дополнение: для правильной работы for-each он должен поддерживать Break[]
и Continue[]
. Я не уверен, как это реализовать. Возможно, это нужно будет каким-то образом реализовать в терминах For, While или Do, поскольку это единственные конструкции цикла, которые поддерживают Break[]
и Continue[]
.
И еще одна проблема с ответами: они едят Return[]
s. То есть, если вы используете цикл ForEach в функции и хотите вернуться из функции из цикла, вы не можете этого сделать. Выдача возврата внутри цикла ForEach, похоже, работает как Continue[]
. Это просто (подождите) сбило меня с толку.