Там какой-либо путь состоит в том, чтобы сделать вложенные циклы n-уровня в Java?

Фил Хаак прекрасно объясняет это в этом блоге . В основном дочернее действие - это действие контроллера, которое вы могли бы вызвать из представления с помощью помощника Html.Action:

@Html.Action("SomeActionName", "SomeController")

Это действие затем выполнит и отобразит его вывод в указанном месте в представлении. Разница с Partial заключается в том, что частичная включает только указанную разметку, нет другого действия, кроме основного действия.

Таким образом, у вас есть основное действие, которое получило запрос и отобразило представление, но из в этом представлении вы можете выполнить несколько дочерних действий, которые пройдут через их независимый жизненный цикл MVC и, в конечном итоге, выведут результат. И все это произойдет в контексте одного HTTP-запроса.

Действия ребенка полезны для создания целых многократно используемых виджетов, которые могут быть встроены в ваши представления и которые проходят через их независимый жизненный цикл MVC.

24
задан jjnguy 9 January 2009 в 02:48
поделиться

6 ответов

Это кажется, что можно хотеть изучить рекурсия.

20
ответ дан 4 revs 16 October 2019 в 07:47
поделиться

Для проблемы нужно больше спецификации. Возможно, рекурсия будет помогать Вам, но иметь в виду, что рекурсия является почти всегда альтернативой повторению, и наоборот. Может случиться так, что 2-уровневый вложенный цикл может быть достаточным для Ваших потребностей. Просто сообщите нам, какую проблему Вы пытаетесь решить.

3
ответ дан John Zwinck 16 October 2019 в 07:47
поделиться

Я на самом деле думал об этом на днях.

пример, который, вероятно, не прекрасен, но достаточно близок к тому, что я думаю, спрашивают, распечатал бы дерево каталогов

public void printTree(directory) {
   for(files in directory) {
      print(file);
      if(file is directory) {
          printTree(file);
      }
   }
}

этот способ, из которого Вы заканчиваете со стеком для циклов, вложенных друг в друге без стычки выяснения точно, как они должны сочетаться.

5
ответ дан Wayne 16 October 2019 в 07:47
поделиться

Вы могли бы хотеть объяснить, что Вы действительно хотите сделать.

, Если внешнее 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();
}
6
ответ дан Michael Burr 16 October 2019 в 07:47
поделиться

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
33
ответ дан joel.neely 16 October 2019 в 07:47
поделиться

Основная идея позади вложенных циклов умножение .

Подробно останавливающийся на ответе 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);
3
ответ дан Apocalisp 16 October 2019 в 07:47
поделиться
Другие вопросы по тегам:

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