Skip to content

Commit c5ca225

Browse files
reduceOrNull & reduceIndexedOrNull
1 parent 786e5c0 commit c5ca225

File tree

2 files changed

+47
-16
lines changed

2 files changed

+47
-16
lines changed

ktorm-core/src/main/kotlin/me/liuwj/ktorm/dsl/Query.kt

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -246,11 +246,7 @@ public inline fun Query.whereWithOrConditions(block: (MutableList<ColumnDeclarin
246246
* If the iterable is empty, the param [ifEmpty] will be returned.
247247
*/
248248
public fun Iterable<ColumnDeclaring<Boolean>>.combineConditions(ifEmpty: Boolean = true): ColumnDeclaring<Boolean> {
249-
if (this.any()) {
250-
return this.reduce { a, b -> a and b }
251-
} else {
252-
return ArgumentExpression(ifEmpty, BooleanSqlType)
253-
}
249+
return this.reduceOrNull { a, b -> a and b } ?: ArgumentExpression(ifEmpty, BooleanSqlType)
254250
}
255251

256252
/**

ktorm-core/src/main/kotlin/me/liuwj/ktorm/entity/EntitySequence.kt

Lines changed: 46 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1238,11 +1238,50 @@ public inline fun <E : Any, R> EntitySequence<E, *>.foldIndexed(
12381238
* Accumulate value starting with the first element and applying [operation] from left to right to current accumulator
12391239
* value and each element.
12401240
*
1241+
* Throws an exception if this sequence is empty. If the sequence can be empty in an expected way, please use
1242+
* [reduceOrNull] instead. It returns `null` when its receiver is empty.
1243+
*
1244+
* The [operation] function takes the current accumulator value and an element, and calculates the next
1245+
* accumulator value.
1246+
*
12411247
* The operation is terminal.
12421248
*/
12431249
public inline fun <E : Any> EntitySequence<E, *>.reduce(operation: (acc: E, E) -> E): E {
1250+
return reduceOrNull(operation) ?: throw UnsupportedOperationException("Empty sequence can't be reduced.")
1251+
}
1252+
1253+
/**
1254+
* Accumulate value starting with the first element and applying [operation] from left to right to current accumulator
1255+
* value and each element with its index in the original sequence.
1256+
*
1257+
* Throws an exception if this sequence is empty. If the sequence can be empty in an expected way, please use
1258+
* [reduceIndexedOrNull] instead. It returns `null` when its receiver is empty.
1259+
*
1260+
* The [operation] function takes the index of an element, current accumulator value and the element itself and
1261+
* calculates the next accumulator value.
1262+
*
1263+
* The operation is terminal.
1264+
*/
1265+
public inline fun <E : Any> EntitySequence<E, *>.reduceIndexed(operation: (index: Int, acc: E, E) -> E): E {
1266+
return reduceIndexedOrNull(operation) ?: throw UnsupportedOperationException("Empty sequence can't be reduced.")
1267+
}
1268+
1269+
/**
1270+
* Accumulate value starting with the first element and applying [operation] from left to right to current accumulator
1271+
* value and each element.
1272+
*
1273+
* Returns `null` if the sequence is empty.
1274+
*
1275+
* The [operation] function takes the current accumulator value and an element, and calculates the next
1276+
* accumulator value.
1277+
*
1278+
* The operation is terminal.
1279+
*
1280+
* @since 3.1.0
1281+
*/
1282+
public inline fun <E : Any> EntitySequence<E, *>.reduceOrNull(operation: (acc: E, E) -> E): E? {
12441283
val iterator = iterator()
1245-
if (!iterator.hasNext()) throw UnsupportedOperationException("Empty sequence can't be reduced.")
1284+
if (!iterator.hasNext()) return null
12461285

12471286
var accumulator = iterator.next()
12481287
while (iterator.hasNext()) {
@@ -1256,22 +1295,18 @@ public inline fun <E : Any> EntitySequence<E, *>.reduce(operation: (acc: E, E) -
12561295
* Accumulate value starting with the first element and applying [operation] from left to right to current accumulator
12571296
* value and each element with its index in the original sequence.
12581297
*
1298+
* Returns `null` if the sequence is empty.
1299+
*
12591300
* The [operation] function takes the index of an element, current accumulator value and the element itself and
12601301
* calculates the next accumulator value.
12611302
*
12621303
* The operation is terminal.
1304+
*
1305+
* @since 3.1.0
12631306
*/
1264-
public inline fun <E : Any> EntitySequence<E, *>.reduceIndexed(operation: (index: Int, acc: E, E) -> E): E {
1265-
val iterator = iterator()
1266-
if (!iterator.hasNext()) throw UnsupportedOperationException("Empty sequence can't be reduced.")
1267-
1307+
public inline fun <E : Any> EntitySequence<E, *>.reduceIndexedOrNull(operation: (index: Int, acc: E, E) -> E): E? {
12681308
var index = 1
1269-
var accumulator = iterator.next()
1270-
while (iterator.hasNext()) {
1271-
accumulator = operation(index++, accumulator, iterator.next())
1272-
}
1273-
1274-
return accumulator
1309+
return reduceOrNull { acc, e -> operation(index++, acc, e) }
12751310
}
12761311

12771312
/**

0 commit comments

Comments
 (0)