Verwendung von Kotlin Range Expressions

1. Einleitung

Ein Bereich ist eine Folge von Werten, die durch einen Anfang, ein Ende und einen Schritt definiert sind.

In diesem kurzen Tutorial sehen wir uns an, wie wir Bereiche in Kotlin definieren und verwenden können.

2. Verwenden von Kotlin-Bereichen

In Kotlin können wir Bereiche mit den Funktionen rangeTo () und downTo () oder dem Operator .. erstellen .

Wir können Bereiche für jeden vergleichbaren Typ verwenden.

Standardmäßig sind sie inklusive, was bedeutet, dass der Ausdruck 1..4 den Werten 1,2,3 und 4 entspricht.

Darüber hinaus gibt es einen weiteren Standard: den Abstand zwischen zwei Werten, der als Schritt bezeichnet wird, mit einem impliziten Wert von 1.

Schauen wir uns nun einige Beispiele an, wie Sie Bereiche erstellen und andere nützliche Methoden verwenden, um sie zu bearbeiten.

2.1. Bereiche erstellen

Bereiche implementieren eine gemeinsame Schnittstelle - ClosedRange. Das Ergebnis einer geschlossenen Reichweite ist eine Progression ( z. B. IntProgression, LongProgression oder CharProgression).

Diese Folge enthält einen Anfang, ein inklusives Ende und einen Schritt und ist ein Subtyp von Iterable, wobei N Int, Long oder Char ist .

Beginnen wir mit der einfachsten Methode zum Erstellen eines Bereichs mithilfe von ".." und in Operatoren:

(i in 1..9)

Wenn wir einen Rückwärtsbereich definieren möchten, können wir auch den Operator downTo verwenden :

(i in 9 downTo 1) 

Wir können diesen Ausdruck auch als Teil einer if- Anweisung verwenden, um zu überprüfen, ob ein Wert zu einem Bereich gehört:

if (3 in 1..9) print("yes")

2.2. Iterierende Bereiche

Während wir Bereiche mit etwas Vergleichbarem verwenden können, benötigen wir einen integralen Typbereich, wenn wir iterieren möchten.

Schauen wir uns nun den Code an, um einen Bereich zu durchlaufen:

for (i in 1.rangeTo(9)) { print(i) // Print 123456789 } for (i in 9.downTo(1)) { print(i) // Print 987654321 }

Der gleiche Anwendungsfall gilt für Zeichen:

for (ch in 'a'..'f') { print(ch) // Print abcdef } for (ch in 'f' downTo 'a') { print(ch) // Print fedcba }

3. Mit dem s tep () Funktion

Die Verwendung der step () -Funktion ist ziemlich intuitiv: Wir können damit einen Abstand zwischen den Werten des Bereichs definieren:

for(i in 1..9 step 2) { print(i) // Print 13579 } for (i in 9 downTo 1 step 2) { print(i) // Print 97531 }

In diesem Beispiel durchlaufen wir die Werte von 1 bis 9 mit einem Schrittwert von 2 vorwärts und rückwärts.

4. Verwenden Sie die Funktion reverse ()

Wie der Name schon sagt, kehrt die Funktion reverse () die Reihenfolge des Bereichs um:

(1..9).reversed().forEach { print(it) // Print 987654321 } (1..9).reversed().step(3).forEach { print(it) // Print 963 }

5. Verwenden Sie die Funktion till ()

Wenn wir einen Bereich erstellen möchten, der das Endelement ausschließt, können wir bis () verwenden:

for (i in 1 until 9) { print(i) // Print 12345678 }

6. Der letzte, erste Schritt Elemente

Wenn wir den ersten, den Schritt oder den letzten Wert des Bereichs finden müssen, gibt es Funktionen, die sie an uns zurückgeben:

print((1..9).first) // Print 1 print((1..9 step 2).step) // Print 2 print((3..9).reversed().last) // Print 3

7. Filterbereiche

Die Funktion filter () gibt eine Liste von Elementen zurück, die einem bestimmten Prädikat entsprechen:

val r = 1..10 val f = r.filter { it -> it % 2 == 0 } // Print [2, 4, 6, 8, 10]

Wir können auch andere Funktionen wie map () und redu () auf unseren Bereich anwenden :

val m = r.map { it -> it * it } // Print [1, 4, 9, 16, 25, 36, 49, 64, 81, 100] val rdc = r.reduce{a, b -> a + b} // Print 55 

8. Andere Dienstprogrammfunktionen

There are many other functions we can apply to our range, like min, max, sum, average, count, distinct:

val r = 1..20 print(r.min()) // Print 1 print(r.max()) // Print 20 print(r.sum()) // Print 210 print(r.average()) // Print 10.5 print(r.count()) // Print 20 val repeated = listOf(1, 1, 2, 4, 4, 6, 10) print(repeated.distinct()) // Print [1, 2, 4, 6, 10] 

9. Custom Objects

It's also possible to create a range over custom objects. For that, the only requirement is to extend the Comparable interface.

An enum is a good example. All enums in Kotlin extend Comparable which means that, by default, the elements are sorted in the sequence they appear.

Let's create a quick Color enum:

enum class Color(val rgb: Int) : Comparable { BLUE(0x0000FF), GREEN(0x008000), RED(0xFF0000), MAGENTA(0xFF00FF), YELLOW(0xFFFF00); } 

And then use it in some if statements:

val range = red..yellow if (range.contains(Color.MAGENTA)) println("true") // Print true if (Color.RED in Color.GREEN..Color.YELLOW) println("true") // Print true if (Color.RED !in Color.MAGENTA..Color.YELLOW) println("true") // Print true

However, as this is not an integral type, we can't iterate over it. If we try, we'll get a compilation error:

fun main(args: Array) { for (c in Color.BLUE.rangeTo(Color.YELLOW)) println(c) // for-loop range must have an iterator() method }

Und wenn wir einen benutzerdefinierten Bereich haben möchten, über den wir iterieren können, müssen wir nur ClosedRange und Iterator implementieren .

10. Schlussfolgerung

In diesem Artikel haben wir gezeigt, wie wir Bereichsausdrücke in Kotlin und verschiedene Funktionen verwenden können, die wir anwenden können.

Wie immer ist der Quellcode auf GitHub verfügbar.