2017-10-20 3 views
3

Gibt es einen Weg in Kotlin für die sum() Operation auf einer gefilterten Liste von Zahlen, ohne tatsächlich die Elemente zuerst herauszufiltern?Summe einer Teilmenge von Zahlen in einer Liste

Ich bin auf der Suche nach so etwas wie folgt aus:

val nums = listOf<Long>(-2, -1, 1, 2, 3, 4) 
val sum = nums.sum(it > 0) 

Antwort

4

Sie Gebrauch von Iterable<T>.sumBy machen können:

/** 
* Returns the sum of all values produced by [selector] function applied to each element in the collection. 
*/ 
public inline fun <T> Iterable<T>.sumBy(selector: (T) -> Int): Int { 
    var sum: Int = 0 
    for (element in this) { 
     sum += selector(element) 
    } 
    return sum 
} 

Sie eine Funktion, um es passieren kann, wenn die Funktion auf 0 negativen Wert umwandelt. Daher werden alle Werte in der Liste zusammengefasst, die größer als 0 sind, da das Hinzufügen von 0 keine Auswirkungen auf das Ergebnis hat.

val nums = listOf<Long>(-2, -1, 1, 2, 3, 4) 
val sum = nums.sumBy { if (it > 0) it.toInt() else 0 } 
println(sum) //10 

Wenn Sie benötigen einen Long Wert zurück, müssen Sie für Long eine Erweiterung schreiben wie Iterable<T>.sumByDouble.

inline fun <T> Iterable<T>.sumByLong(selector: (T) -> Long): Long { 
    var sum: Long = 0 
    for (element in this) { 
     sum += selector(element) 
    } 
    return sum 
} 

Dann kann die toInt() Umwandlung entfernt werden.

nums.sumByLong { if (it > 0) it else 0 } 

Wie @Ruckus T-Boom vorgeschlagen, if (it > 0) it else 0 kann mit Long.coerceAtLeast() vereinfacht werden, die den Wert selbst oder die angegebenen Minimalwert zurückgibt: kann

nums.sumByLong { it.coerceAtLeast(0) } 
+2

Sie 'it.coerceAtLeast nutzen (0)' anstelle von 'if (it> 0) ist es sonst 0' –

Verwandte Themen