Существует ли параметр, который я могу использовать в Java, который работает со всеми циклами foreach?

Используйте обратную связь :

{% for role in current_project.role_set.all %}

  {{ role.job.name }}
  {{ role.user.username }}

{% endfor %}

РЕДАКТИРОВАТЬ:

Есть ли способ сделать это в модели или в представлении вместо (не используя другой переменная), как prefetch_related? Потому что метод в шаблоне генерирует несколько дубликатов SQL запросов.

blockquote>

IIRC вы можете применить prefetch_related и select_related к набору запросов Project в вашем представлении, т.е.

qs = Project.objects.prefetch_related(....).select_related(...)
current_project = qs.get(pk=...)

, но это из памяти, и у меня нет времени перепроверить это прямо сейчас ...

7
задан Dan Lew 20 April 2009 в 18:31
поделиться

6 ответов

Я бы предложил использовать Iterable , Collection или List как тип параметра.

IMO, коллекции следует отдавать предпочтение ссылочным массивам. Если у вас есть массив , Arrays.asList хорошо выполнит преобразование. Arrays.asList позволяет получить и установить обратно в массив, но, очевидно, не «структурные» модификации, которые могли бы изменить длину массива.

myFun(Arrays.asList(arr));

Возможно, вам придется использовать групповые символы в крайних / общих случаях. [1246 Следует отметить, что Collections.toArray и Arrays.asList работают немного по-разному. asList сохраняет исходный массив для поддержки коллекции, поэтому изменения в коллекции будут отражены в массиве. Коллекция. toArray делает (мелкую) копию данных коллекции. Создание копии часто является тем, что вы хотели бы в любом случае, если вы возвращаете массив. Асимметрично, если вы передаете в качестве аргумента, вы обычно не копируете (если не сохраняете как поле).

9
ответ дан 6 December 2019 в 14:09
поделиться

вы не можете , java Arrays не реализует Iterable:

public static int sum(Iterable<Integer> elements) {
    int s = 0;

    for (int i : elements) {
        s += i;
    }

    return s;
}

public static void main(String[] args) {
    L1: System.out.println(sum(1,2,3));
    L2: System.out.println(sum(Arrays.asList(1,2,3)));
    L3: System.out.println(sum(new int[] { 1,2,3 }));
}

это приводит к двум ошибкам времени компиляции в (L1 и L3); так что вы должны разработать свой метод для приема Iterable (Collections) и / или Array, по крайней мере один метод должен выполнить некоторое преобразование (в / из массива)

ВОЗМОЖНОЕ РЕШЕНИЕ :

вы можете попробовать использовать адаптер:

public class ArrayIterator<T> implements Iterator<T> {

    private final T[] array;
    private int i;

    public ArrayIterator(T[] anArray) {
        array = anArray;
        i = 0;
    }

    public boolean hasNext() {
        return i < array.length;
    }

    public T next() {
        return array[i++];
    }

    public void remove() {
        throw new UnsupportedOperationException();
    }
}

private static int sum(final Integer ... elements) {
    return sum(new Iterable<Integer>() {

        public Iterator<Integer> iterator() {
            return new ArrayIterator<Integer>(elements);
        }
    });
}

вам следует обращать внимание только при работе с примитивными массивами; когда вы используете только ссылочный объект (ваш случай) ArrayIterator + анонимный класс - это круто

надеюсь, что это поможет

3
ответ дан 6 December 2019 в 14:09
поделиться

Используйте Iterable . Вот для чего это.

Как вы сказали, Iterable не будет обрабатывать массивы.

Вы не хотите использовать несколько методов, оборачивающих друг друга. Это исключает Arrays.asList и Collection.toArray .

Таким образом, ответ на ваш вопрос - нет, пути нет. Но если вы можете использовать списки , зачем вам когда-либо использовать массивы?

Я все равно остановлюсь здесь на Iterable . Мне нравится это лучше, чем Collection , потому что в прошлом у меня были классы, которые реализовали Iterable , но не были коллекциями; это облегчало им ленивый поиск значений по мере необходимости, и я мог использовать цикл foreach для них.

5
ответ дан 6 December 2019 в 14:09
поделиться

Есть небольшая известная особенность Java Generics в Java 1.5+, где вы можете использовать в ваших вызовах методов и конструкторах. Вы можете использовать , и тогда все, что с ними связано, будет иметь доступ только к методам Object. На самом деле вам может понадобиться что-то вроде этого:

List<? extends MyCrustaceans> seaLife = new ArrayList<? extends MyCrustaceans>();
MyShrimp s = new MyShrimp("bubba");
seaLife.add(s);
DoStuff(seaLife);

...

public static void DoStuff(List<? extends MyCrustaceans> seaLife)
{
    for (MyCrustaceans c : seaLife) {
        System.out.println(c);
    }
}

Итак, если у вас есть базовый класс (например, MyCrustaceans), вы можете использовать любые методы этого базового класса в DoStuff (или в классе Object, если ваш параметр ] ). Есть похожая особенность , где он принимает параметр, который является супертипом данного типа, а не подтипом. Существуют некоторые ограничения на то, для чего вы можете использовать «расширяет» и «супер» таким образом.

0
ответ дан 6 December 2019 в 14:09
поделиться
public static void myFun(Collection<MyClass> collection) {
    for (MyClass mc : collection) {
        // Stuff is processed here
    }
}
-3
ответ дан 6 December 2019 в 14:09
поделиться

Краткий ответ: нет, не существует единой сигнатуры метода, которая бы безошибочно принимала тип Iterable и массив. Очевидно, вы могли бы просто принять Object , но это также было бы хаком.

Ответ с длинным ответом: поскольку расширенный для -loop эффективно определяется дважды (один раз для массивов). и один раз для Iterable ), вам также потребуется предоставить два перегруженных метода:

public static void myFun(SomeClass[] array) {
    for (SomeClass sc : array) {
        doTheProcessing(sc);
    }
}

public static void myFun(Iterable<? extends SomeClass> iterable) {
    for (SomeClass sc : iterable) {
        doTheProcessing(sc);
    }
}

Хотя источник этих двух методов выглядит точно так же, вам нужно определить его дважды (если только Конечно, вы оборачиваете массив в свою собственную итерируемую , как обрисовано в общих чертах @dfa).

1
ответ дан 6 December 2019 в 14:09
поделиться
Другие вопросы по тегам:

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