Вы можете использовать $ expr (оператор версии 3.6 mongo), чтобы использовать функции агрегирования в обычном запросе.
Сравнить query operators
и aggregation comparison operators
.
Для скалярных массивов
db.col.find({$expr:{$gt:[{$arrayElemAt:["array", -1]}, value]}})
Для встроенных массивов - используйте выражение $arrayElemAt
с точечной нотацией для проецирования последнего элемента.
db.col.find({$expr:{$gt:[{"$arrayElemAt": ["$array.field", 0]}, value]}})
Пружина @Query
код
@Query("{$expr:{$gt:[{$arrayElemAt:[\"array\", -1]}, ?0]}}")
ReturnType MethodName(ArgType arg);
Оба StatementExpressionList
и ] LocalVariableDeclaration
определены где-нибудь на странице. Я скопирую их сюда:
StatementExpressionList:
StatementExpression
StatementExpressionList , StatementExpression
StatementExpression:
Assignment
PreIncrementExpression
PreDecrementExpression
PostIncrementExpression
PostDecrementExpression
MethodInvocation
ClassInstanceCreationExpression
и
LocalVariableDeclaration:
VariableModifiers Type VariableDeclarators
VariableDeclarators:
VariableDeclarator
VariableDeclarators , VariableDeclarator
VariableDeclarator:
VariableDeclaratorId
VariableDeclaratorId = VariableInitializer
VariableDeclaratorId:
Identifier
VariableDeclaratorId [ ]
VariableInitializer:
Expression
ArrayInitializer
Нет особого смысла в дальнейшем изучении грамматики; Я надеюсь, что это достаточно легко читать и так.
Это означает, что вы можете иметь или любое количество Выражений Заявления
, разделенных запятыми, или ] a LocalVariableDeclaration
в разделе ForInit
. А LocalVariableDeclaration
может состоять из любого количества пар « переменная = значение
», разделенных запятыми, которым предшествует их тип.
Итак, это допустимо:
for (int i = 0, j = 0, k = 0;;) { }
, потому что « int i = 0, j = 0, k = 0
» является допустимым LocalVariableDeclaration
. И это допустимо:
int i = 0;
String str = "Hello";
for (str = "hi", i++, ++i, sayHello(), new MyClass();;) { }
, потому что все эти случайные вещи в инициализаторе квалифицируются как StatementExpressions
.
И поскольку StatementExpressionList
разрешен в части обновления цикла for, это также верно:
int i = 0;
String str = "Hello";
for (;;str = "hi", i++, ++i, sayHello(), new MyClass()) { }
Вы начинаете понимать?
Предупреждение: мы ожидаем увидеть очень простое и очень знакомое содержание в скобках. Выход за пределы
for (int i = 0; i < n; i++)
может запутать будущих читателей вашего кода. Иногда вам нужно выполнить итерацию в обратном порядке - даже условия начала и окончания вызывают проблемы у многих программистов (это n, n-1, n + 1? Это> 0,> = 0, ...?)
Есть обстоятельства, в которых уместно уточнить детали. Я'
StatementExpressionList
означает, что вы можете делать:
int x = 0;
int y = 0;
int z = 0;
for ( x++, y++; x+ y < z; z++) {
// whatever
}
где x ++, y ++ - это список, список выражений. Обычно операторы, которые вы хотите выполнить в начале цикла.
LocalVariableDeclaration выглядит как
int j = 0, i = 0, k = 0;
, поэтому
for ( int j = 0, i = 0, k = 0; i+j+k < 10; i++, j++, k++ ){
// whatever
}
В основном, для простого цикла FOR:
for (startCondition; endCondition; increment)
в startCondition вы устанавливаете начальное значение переменной, используемой для запуска цикла; во многих случаях вы увидите это как i
int i = 0
В endCondition вы указываете сравнение, во время которого цикл продолжает выполняться. Итак, если вы хотите остановить цикл, когда i = 15, вы должны поставить
i <= 15
OR
i != 15
. Вы также можете делать такие вещи, как сравнение с логическими значениями, такими как
i == true
с приращением, вы указываете, насколько переменная счетчика должна приращение после каждого цикла. Если вы хотите просто увеличить на 1, вы должны указать
i++
. Можно сделать намного более сложным с большим количеством выражений в startCondition и endCondition и с несколькими счетчиками, но это простой цикл FOR.
Вторым оператором цикла for (условным) может быть все, что оценивается как логическое или логическое. Обычно это что-то вроде i
hasMore ()
, (x> y) == bool
или что-то вроде myclient.getMapOfIntsToBools (). Get (i)
. До тех пор, пока результатом выражения является логическое значение, не имеет значения, сколько оно длится.
Две другие части могут быть, по существу, любым отдельным оператором: каким бы ни был окончательный тип возвращаемого значения, он игнорируется (как если бы это было на пустой строке). Первый оператор всегда выполняется ровно один раз, в начале первого цикла, а второй - в конце каждого цикла.
Альтернативный способ думать об этом так:
if (A; B; C){
...
}
превращается в это:
A
while (B){
...
C
}
A и C могут быть любым отдельным утверждением, которое вы хотите, чтобы они были (включая ничего). B должен быть чем-то, что оценивается как логическое.
BasicForStatement: для (ForInitopt; Expressionopt; ForUpdateopt) Оператор
for состоит из ForInit, Expression и ForUpdate, каждый из которых является необязательным
ForInit: ЗаявлениеВыражениеСписок LocalVariableDeclaration ForInit - это список выражений и выражений, разделенных запятыми (см. Ниже), или объявление локальной переменной
ForUpdate: StatementExpressionList
ForUpdate - это список утверждений и выражений, разделенных запятыми ... В принципе, вы можете указать:
Задание
PreIncrementExpression
PreDecrementExpression
PostIncrementExpression
PostDecrementExpression
MethodInvocation
ClassInstanceCreationExpression
StatementExpressionList: Заявление StatementExpressionList, StatementExpression
Что такое оператор:
Последовательность выполнения программы контролируется операторами, которые выполняются для их эффекта и не имеют значений.
Некоторые утверждения содержат другие заявления как часть их структуры; такие другие заявления части заявления. Мы говорим это утверждение S сразу содержит оператор U, если нет оператора T отличное от S и U, такое что S содержит T, а T содержит U. В таким же образом некоторые утверждения содержат выражения как часть их структура.
И выражение
Большая часть работы в программе выполняется путем оценки выражений либо на предмет их побочных эффектов, таких как присваивание переменным, либо их значений, которые могут использоваться в качестве аргументов или операндов. в более крупных выражениях, или чтобы повлиять на последовательность выполнения в операторах, или и то, и другое.
Таким образом, в основном вы можете иметь любое допустимое Java-выражение в середине (вам не нужно сравнение), но все же это выражение должно возвращать логическое значение .. .
for(startCondition(s); endCondition(s); Action) {}
Пока startCondition (s) и endCondition (s) оцениваются как логические (истина или ложь, 1 или 0 в зависимости от языка), вы можете иметь сколько угодно «длинный» список условий.
Вы можете поместить
for (stmt a, stmt b, stmt, c ....; stmt 1; alpha, beta, omega, ...) {
}
где stmt: statement;
a, b, c и т. д. могут быть
определение локальных переменных или другие операторы
for(int a=0,b=0;;){}
будут объявлять и инициализировать как a, так и b равными 0;
for(a=i,b=a+1;;){}
присваивает a и b этим значениям
С итераторами вы можете
for(Iterator it= my_list.iterator();;){}
1, 2, 3 и так далее должны возвращать логические значения
, поэтому вы не можете указать что-то вроде
for (;a++;)
, но можете
for (;a<b;)
или
for(;it.hasNext();)
, которые в основном представляют собой цикл while.
или вообще ничего :)
for(int a=0;;a++)
Что касается альфы, омега .. часть, следует использовать оператор присваивания
for(;;a){}
не будет компилироваться, но
for(;;a++){}
for(;;a=b;a++){}
будет.
Затем у вас есть конструкция foreach , которая намного проще
for (A a:getAList())
и выполняет итерацию по всему списку, a имеющий текущий элемент. Управляющая переменная не требуется.
Для перевода спецификаций с помощью цикла
for (initFor; endCondition; update)
startCondition
- это список операторов, значения которых отбрасываются (включая отсутствие операторов). Они указывают LocalVariableDeclaration
, чтобы отметить, что если объявление локальной переменной находится в операторах (например, int x = 0), тогда локальная переменная "привязана" к блоку оператора for (то есть значение не будет быть доступным вне блока или оператора for).
endCondition
- это логическое выражение. Опять же, это необязательно (в противном случае цикл продолжается вечно)
update
- это список операторов, обычно обрабатывающих обновления, необходимые после каждого цикла.
Все три предложения цикла for необязательны, но точка с запятой должна быть там.
В первом предложении цикла for вы можете поместить любое количество операторов, разделенных запятыми. Или, в качестве альтернативы (но вы не можете смешивать), вы можете объявить новые переменные одного типа, доступные для цикла for (например, int i = 1, j = 2). Любые объявленные здесь переменные доступны для оператора после цикла for (или для операторов, если вы используете фигурные скобки).
Второе предложение цикла for - это один оператор, который возвращает логическое значение. Это будет оценено, чтобы рассмотреть, следует ли продолжить цикл for.
Третье предложение цикла for может содержать любое количество операторов, разделенных запятой, но не может объявлять какие-либо переменные.
Вы получаете много ответов, которые на самом деле не отвечают на ваш вопрос. Правильный ответ - вы можете поставить абсолютно все, что захотите. Вам даже не нужно допустимое конечное условие, если в вашем цикле for есть оператор break
. Вам также не нужны три оператора, как в случае использования цикла Iterator.
EDIT: Хорошо, не совсем верно. Вы не можете инициализировать новую переменную после первой точки с запятой.
Вы можете обнаружить, что для каждой нотации часто проще и яснее. Я бы посоветовал использовать для каждого цикла всякий раз, когда это необходимо. например,
for(Element element: arrayOfElement) { /* stuff */ }
// or
for(Element element: iterableOfElement) { /* stuff */ }
Коллекция, Набор и Список можно итерировать, но вы можете создавать свои собственные.
у вас может быть несколько утверждений; затем одно условие, которое оценивается в каждом цикле, и, наконец, еще один набор операторов