Skip to content

Commit

Permalink
Add withEach and withEachIndexed Iterable extensions, prompt function (
Browse files Browse the repository at this point in the history
…#17)

* add withEach and withEachIndexed Iterable extensions

* add prompt function

* added Prompt documentation

* fixed detekt compliance
  • Loading branch information
KamilKurde authored Apr 12, 2022
1 parent 566e300 commit 4491c9f
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 1 deletion.
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ Following functions are the most popular ones.
* `Iterable<A>.zip(b: Iterable<B>, c: Iterable<C>, transform: (a: A, b: B, c: C) -> V)` - zip with three collections instead of two
* `Iterable<T>.sumByFloat(selector: (T) -> Float)` - sums iterable by float selector, because `sumOf` from stdlib does not have
implementation for Floats
* `Iterable<T>.withEach(action: T.() -> Unit)` - performs the given action with each element as a receiver
* `Iterable<T>.withEachIndexed(action: T.(index: Int) -> Unit)` - performs the given action with each element as a receiver, providing sequential index with the element

#### [Map Extensions](src/main/kotlin/pw/forst/katlib/MapExtensions.kt)

Expand Down Expand Up @@ -230,3 +232,7 @@ byteBuffer.applyIf(shouldReadInt) { getInt() }
* `Array<out T?>.filterNotNull(): Array<T>` - returns an array containing all elements that are not `null`
* `Array<out T>.minus(element: T): Array<T>` - returns an array containing all elements of the original collection without the first occurrence of the given element
* `Array<out T>.minus(elements: Array<out T>): Array<T>` - returns an array containing all elements of the original collection except the elements contained in the given elements array

#### [Prompt](src/main/kotlin/pw/forst/katlib/Prompt.kt)

* `prompt(promptText: String, exceptionHandler: (e: Exception) -> String? = { null }, transform: (input: String) -> R): R` - prompts user and applies transform to input, invokes exceptionHandler if transform threw an Exception, and repeats prompt
2 changes: 1 addition & 1 deletion detekt-config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ exceptions:
active: true
TooGenericExceptionCaught:
active: true
excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**']
excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**', '**/Prompt.kt']
exceptionNames:
- 'ArrayIndexOutOfBoundsException'
- 'Error'
Expand Down
10 changes: 10 additions & 0 deletions src/main/kotlin/pw/forst/katlib/IterableExtensions.kt
Original file line number Diff line number Diff line change
Expand Up @@ -643,3 +643,13 @@ inline fun <T> Iterable<T>.sumByFloat(selector: (T) -> Float): Float {
return sum
}

/**
* Performs the given action with each element as a receiver.
*/
inline fun <T> Iterable<T>.withEach(action: T.() -> Unit) = forEach { it.action() }

/**
* Performs the given [action] with each element as a receiver, providing sequential index with the element.
* @param [action] function that takes the index of an element and performs the action on the element.
*/
inline fun <T> Iterable<T>.withEachIndexed(action: T.(index: Int) -> Unit) = forEachIndexed{ index, it -> it.action(index)}
27 changes: 27 additions & 0 deletions src/main/kotlin/pw/forst/katlib/Prompt.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package pw.forst.katlib

/**
* Prints @param [promptText], reads input from console and applies @param [transform] to it.
* If @param [transform] throws an exception on user input, @param [exceptionHandler] will be invoked,
* and prompt will be repeated.
*
* Example: snippet below will ask user for input until given input can be parsed to Double
* ```
* prompt(
* "input number:",
* { "this is not a number" },
* )
* { it.toFloat() }
* ```
* @return user input with transform applied
*/
fun <R> prompt(promptText: String, exceptionHandler: (e: Exception) -> String? = { null }, transform: (input: String) -> R): R {
while (true) {
print(promptText)
try {
return transform(readln())
} catch (e: Exception) {
exceptionHandler(e)?.let { println(it) }
}
}
}
17 changes: 17 additions & 0 deletions src/test/kotlin/pw/forst/katlib/IterableExtensionsTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -352,4 +352,21 @@ internal class IterableExtensionsTest {
val empty = listOf<Float>()
assertEquals(0f, empty.sumByFloat { it * 2f })
}

@Test
fun `test withEach`() {
val pairs = List(100){ Pair(it, it * 2) }
pairs.withEach {
assertEquals(first * 2, second)
}
}

@Test
fun `test withEachIndexed`()
{
val pairs = List(100){ it }
pairs.withEachIndexed { index ->
assertEquals(index, this)
}
}
}

0 comments on commit 4491c9f

Please sign in to comment.