Фил Хаак прекрасно объясняет это в этом блоге . В основном дочернее действие - это действие контроллера, которое вы могли бы вызвать из представления с помощью помощника Html.Action
:
@Html.Action("SomeActionName", "SomeController")
Это действие затем выполнит и отобразит его вывод в указанном месте в представлении. Разница с Partial заключается в том, что частичная включает только указанную разметку, нет другого действия, кроме основного действия.
Таким образом, у вас есть основное действие, которое получило запрос и отобразило представление, но из в этом представлении вы можете выполнить несколько дочерних действий, которые пройдут через их независимый жизненный цикл MVC и, в конечном итоге, выведут результат. И все это произойдет в контексте одного HTTP-запроса.
Действия ребенка полезны для создания целых многократно используемых виджетов, которые могут быть встроены в ваши представления и которые проходят через их независимый жизненный цикл MVC.
Это кажется, что можно хотеть изучить рекурсия.
Для проблемы нужно больше спецификации. Возможно, рекурсия будет помогать Вам, но иметь в виду, что рекурсия является почти всегда альтернативой повторению, и наоборот. Может случиться так, что 2-уровневый вложенный цикл может быть достаточным для Ваших потребностей. Просто сообщите нам, какую проблему Вы пытаетесь решить.
Я на самом деле думал об этом на днях.
пример, который, вероятно, не прекрасен, но достаточно близок к тому, что я думаю, спрашивают, распечатал бы дерево каталогов
public void printTree(directory) {
for(files in directory) {
print(file);
if(file is directory) {
printTree(file);
}
}
}
этот способ, из которого Вы заканчиваете со стеком для циклов, вложенных друг в друге без стычки выяснения точно, как они должны сочетаться.
Вы могли бы хотеть объяснить, что Вы действительно хотите сделать.
, Если внешнее for
циклы делают только управление количеством, то Вашим вложенным for
циклы является просто более сложный способ выполнить итерации количеством, которое могло быть обработано синглом for
цикл.
, Например:
for (x = 0; x < 10; ++x) {
for (y = 0; y < 5; ++y) {
for (z = 0; z < 20; ++z) {
DoSomething();
}
}
}
эквивалентно:
for (x = 0; x < 10*5*20; ++x) {
DoSomething();
}
jjnguy является правильным; рекурсия позволяет Вам динамично создать вложение переменной глубины. Однако Вы не получаете доступ к данным из внешних слоев без немного большего количества работы. "in-line-nested" случай:
for (int i = lo; i < hi; ++i) {
for (int j = lo; j < hi; ++j) {
for (int k = lo; k < hi; ++k) {
// do something **using i, j, and k**
}
}
}
сохраняет переменные i
, j
, и k
в объеме для самого внутреннего тела для использования.
Вот один быстрый взлом, чтобы сделать это:
public class NestedFor {
public static interface IAction {
public void act(int[] indices);
}
private final int lo;
private final int hi;
private final IAction action;
public NestedFor(int lo, int hi, IAction action) {
this.lo = lo;
this.hi = hi;
this.action = action;
}
public void nFor (int depth) {
n_for (0, new int[0], depth);
}
private void n_for (int level, int[] indices, int maxLevel) {
if (level == maxLevel) {
action.act(indices);
} else {
int newLevel = level + 1;
int[] newIndices = new int[newLevel];
System.arraycopy(indices, 0, newIndices, 0, level);
newIndices[level] = lo;
while (newIndices[level] < hi) {
n_for(newLevel, newIndices, maxLevel);
++newIndices[level];
}
}
}
}
Эти IAction
интерфейс предусматривает роль управляемого действия, которое берет массив индексов как аргумент act
метод.
В этом примере, каждый экземпляр NestedFor
настроен конструктором с итеративными пределами и действием, которое будет выполнено самым внутренним уровнем. Параметр nFor
метод определяет, как глубоко вложить.
Вот демонстрационное использование:
public static void main(String[] args) {
for (int i = 0; i < 4; ++i) {
final int depth = i;
System.out.println("Depth " + depth);
IAction testAction = new IAction() {
public void act(int[] indices) {
System.out.print("Hello from level " + depth + ":");
for (int i : indices) { System.out.print(" " + i); }
System.out.println();
}
};
NestedFor nf = new NestedFor(0, 3, testAction);
nf.nFor(depth);
}
}
и (частичный) вывод от его выполнения:
Depth 0
Hello from level 0:
Depth 1
Hello from level 1: 0
Hello from level 1: 1
Hello from level 1: 2
Depth 2
Hello from level 2: 0 0
Hello from level 2: 0 1
Hello from level 2: 0 2
Hello from level 2: 1 0
Hello from level 2: 1 1
Hello from level 2: 1 2
Hello from level 2: 2 0
Hello from level 2: 2 1
Hello from level 2: 2 2
Depth 3
Hello from level 3: 0 0 0
Hello from level 3: 0 0 1
Hello from level 3: 0 0 2
Hello from level 3: 0 1 0
...
Hello from level 3: 2 1 2
Hello from level 3: 2 2 0
Hello from level 3: 2 2 1
Hello from level 3: 2 2 2
Основная идея позади вложенных циклов умножение .
Подробно останавливающийся на ответе Michael Burr, если внешнее for
циклы делают только управление количеством, то Вашим вложенным for
циклы [более чем 117] количества является просто более сложный способ выполнить итерации по продукту количеств с синглом for
цикл.
Теперь, давайте расширим эту идею Спискам. При итерации более чем трех списков во вложенных циклах это - просто более сложный способ выполнить итерации по продукту списков с единственным циклом. Но как Вы выражаете продукт трех списков?
Первый, нам нужен способ выразить продукт типов. Продукт двух типов X
и Y
может быть выражен как универсальный тип как [1 111]. Это - просто значение, которое состоит из двух значений, одного из типа X
, другого типа Y
. Это похоже на это:
public abstract class P2<A, B> {
public abstract A _p1();
public abstract B _p2();
}
Для продукта трех типов, мы просто имеем P3<A, B, C>
с очевидным третьим методом. Продукт трех списков, тогда, достигается путем распределения функтора Списка по типу продукта. Таким образом, продукт [1 115], List<Y>
, и List<Z>
просто List<P3<X, Y, Z>>
. Можно тогда выполнить итерации по этому списку с единственным циклом.
библиотека Functional Java имеет List
тип, который поддерживает умножающиеся списки вместе с помощью первоклассных функций и типов продукта (P2, P3, и т.д. которые также включены в библиотеку).
, Например:
for (String x : xs) {
for (String y : ys) {
for (String z : zs) {
doSomething(x, y, z);
}
}
}
эквивалентно:
for (P3<String, String, String> p : xs.map(P.p3()).apply(ys).apply(zs)) {
doSomething(p._1(), p._2(), p._3());
}
Движение далее с Функциональным Java, можно сделать doSomething
первоклассный, следующим образом. Скажем, doSomething
возвраты Строка:
public static final F<P3<String, String, String>, String> doSomething =
new F<P3<String, String, String>, String>() {
public String f(final P3<String, String, String> p) {
return doSomething(p._1(), p._2(), p._3());
}
};
Тогда можно устранить для цикла в целом и собрать результаты всех приложений [1 122]:
List<String> s = xs.map(P.p3()).apply(ys).apply(zs).map(doSomething);