Is there a standard Kotlin function for splitting a Sequence into a head and a tail? - kotlin

I'm thinking of something with a signature like fun <T> Sequence<T>.destruct(): Pair<T, Sequence<T>>? which would return null for an empty sequence, otherwise a pair of the first and rest of the receiver.

I believe the answer is "no." This page lists all of the standard Sequence functions, and a search for "pair" doesn't turn up anything that seems to match what you want.
That said, there is a standard firstOrNull() function as well as a drop() function, so you could write your own pretty easily:
fun <T> Sequence<T>.destruct() =
firstOrNull()?.let { it to drop(1) }
If you are working with sequences that can only be consumed once, the above won't work (as both firstOrNull() and (eventually) DropSequence will invoke the receiver's iterator() method). You could work around this by following the same general idea but being more explicit about how iterator() is called:
fun <T> Sequence<T>.destruct(): Pair<T, Sequence<T>>? {
val iterator = iterator()
return if (iterator.hasNext()) {
iterator.next() to iterator.asSequence()
} else {
null
}
}

Related

How to slice vararg argument

I wrote an extension function to get an element of an JSON object by its name:
fun JSONObject.obj (name: String): JSONObject? =
try { this.getJSONObject(name) }
catch (e: JSONException) { null }
Now I want to extend this for nested JSON objects. I wrote the following:
tailrec fun JSONObject.obj (first: String, vararg rest: String): JSONObject? =
if (rest.size == 0)
obj(first)
else
obj(first)?.obj(rest[0], *rest.drop(1).toTypedArray())
But this looks quite inefficient to me.
What is the best way to slice a vararg argument?
We could use vararg only in the public function, but then internally use list for recursion:
fun JSONObject.obj (first: String, vararg rest: String): JSONObject? = obj(first, rest.asList())
private tailrec fun JSONObject.obj (first: String, rest: List<String>): JSONObject? =
if (rest.size == 0)
obj(first)
else
obj(first)?.obj(rest[0], rest.subList(1, rest.size))
Both asList() and subList() don't copy data, but only wrap the existing collection. Still, this is far from ideal, because it creates a new object for each iteration and it may create a chain of views (it depends on internal implementation of subList()). Alternatively, the internal function could receive an array and offset - this will solve both above problems.
Generally, I suggest to not try turning Kotlin into something it is not. It has limited support for functional constructs, but it is not a functional language. Without the linked list implementation which could be easily split into head and tail, this style of code will be always inefficient and/or cumbersome. You can look for such implementation, for example in Arrow or kotlinx.collections.immutable. The latter has ImmutableList with optimized subList() - you can use it with the solution provided above to avoid creating a chain of lists.
Update
As a matter of fact, basic lists implementations in the Java stdlib also provide optimized subList(): AbstractList.java. Therefore, the above solution using simply asList() should be fine, at least when targeting JVM.
Instead of slicing, why don't you try just iterating over all the objects and getting the JSONObjects? I think this would be much more efficient.
fun JSONObject.obj(vararg names: String): JSONObject? {
var jsonObject = this
for (name in names) {
if (!jsonObject.has(name))
return null
jsonObject = jsonObject.getJSONObject(name)
}
return jsonObject
}

How to create a custom iterator in kotlin and add to existing class?

Hello I am trying to add a custom iterator for example to a Pair class from kotlin package to be able to use instance of that class in a for loop
Let's assume this is what I want to be able to do:
val pair: Pair<Int, String> = Pair(1, "sample data")
for (element in pair) {
println(element)
}
I know that there are plenty other ways to print elements from a pair but I specifically want to be able to use pair in a for loop and I need to add iterator() object with next() and hasNext() methods implementation to Pair class
You can do this by providing the iterator() operator for your object, either as a member function or extension function. Example using an extension function:
fun main() {
val pair: Pair<Int, String> = Pair(1, "sample data")
for (element in pair) {
println(element)
}
}
operator fun <T> Pair<T, T>.iterator(): Iterator<T> = listOf(first, second).iterator()
However, you need to be aware that this way you partially lose strongly typing. element can only be a common supertype of all elements, in most cases simply Any?.
You can read more about this in the official documentation: https://kotlinlang.org/docs/control-flow.html#for-loops

Get index of given element from array extension function kotlin

I'd like to understand Kotlin extension functions more and am trying to implement an extension function for a List, to get the index of an element by passing the value of the position (if that makes sense).
What I have:
fun List<String>.getItemPositionByName(item: String): Int {
this.forEachIndexed { index, it ->
if (it == item)
return index
}
return 0
}
Although this works fine, I would need the same thing for Int too.
To my question, is there a way of combining this into one extension function instead of two seperate ones? I acknowledge that this isn't a lot of code and wouldn't hurt to be duplicated but out of interest and for future references.
I'm aware of this question Extension functions for generic classes in Kotlin where the response is - as I understand it at least - "doesn't quite work like this, but I don't really need it for type but "just" for String and Int.
Kotlin supports what C++ people would refer to as specialization to a certain degree. It works just fine for very basic types like you're using so what you're asking of is definitely possible.
We can declare the following declarations. Of course you could just duplicate the code and you'd be on your way.
public fun List<String>.getItemPositionByName(item: String) = ...
public fun List<Int>.getItemPositionByName(item: String) = ...
If you're not a fan of repeating the code, the idiomatic way would be to make use of file-private functions and simply delegating to the private function.
private fun <T> getItemImpl(list: List<T>, item: T): Int {
list.forEachIndexed { index, it ->
if (it == item)
return index
}
return -1
}
public fun List<String>.getItemPositionByName(item: String) = getItemImpl(this, item)
public fun List<Int>.getItemPositionByName(item: Int) = getItemImpl(this, item)
This limits the getItemImpl which is fully generic to the current file you're in while the Int and String specializations are publicly available anywhere else.
Attempting to call getItemPositionByName on any list which is not of type List<Int> or List<String> will fail with a type error.
Kotlin Playground Link: https://pl.kotl.in/NvIRXwmpU
And just in case you weren't aware, the method you're implementing already exists in the standard library (https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/index-of.html)
The Kotlin standard library already has a function that does this: indexOf().
val one = listOf("a", "b", "c").indexOf("b")
check(one == 1)
One option is to look at the implementation of that function.
There is also the first() function, which you could use if you wanted write your own generic version:
fun <T> List<T>.getItemPositionByName(item: T) = withIndex()
.first { (_, value) -> item == value }
.index
fun main(args: Array<String>) {
val one = listOf("a", "b", "c").getItemPositionByName("b")
check(one == 1)
}
Or, rewriting your original version to use generics:
fun <T> List<T>.getItemPositionByName(item: T): Int {
this.forEachIndexed { index, it ->
if (it == item)
return index
}
return 0
}

Kotlin: generic cast function parameter

Taking my first steps in Kotlin, I'm struggling to find the correct signature for a function that receives an instance of a known class along with the desired output class and then looks in a map of converter lambdas whether the conversion can be done.
Here's an example for Long:
private fun <T> castLong(value: Long, clazz: Class<out T>): T {
// map lookup removed for simplicity
return when (clazz) {
String::class.java -> { value.toString() }
else -> { throw IllegalArgumentException("Unsupported Cast") }
}
}
Where T is the class of the desired return value - let's say String. One should be able to call castLong(aLongValue, String::class.java) and receive an instance of String.
But the compiler says:
Type mismatch: inferred type is String but T was expected
This seems like it should be possible as it is quite straightforward so far but even playing around with reified and other constructs didn't yield any better results.
It happens because it can't smart cast String to T, you have to manually cast it.
Furthermore, since you said you are taking your first steps in Kotlin, I leave here two other "advices" not strictly related to your question:
you can get the class of T making it reified
the brackets of a case using when aren't necessary if the case is one line
private inline fun <reified T> castLong(value: Long): T {
// map lookup removed for simplicity
return when (T::class.java) {
String::class.java -> value.toString()
else -> throw IllegalArgumentException("Unsupported Cast")
} as T
}

Coding convention for empty functions that need to be overridden in Kotlin

Accourding to the very short Coding Conventions there is no answer for the opimal way of writing down empty functions in Kotlin.
Example:
ani.setAnimationListener(object: Animation.AnimationListener {
override fun onAnimationRepeat(animation: Animation?) = Unit
override fun onAnimationStart(animation: Animation?) {}
override fun onAnimationEnd(animation: Animation?) =
activity.runOnUiThread { loadLists() }
})
Here only one of the 3 necessary Methods of AnimationListener (Android) is used.
Which type of empty Method should be used?
Single Expression (fun name() = Unit) or the traditional way used in Java (fun name() {})?
I personally like the = Unit-Way more because that seems to be meant the way of shorting functions down to one line. But {} is shorter yet older and probably more ugly.
And is there any better/shorter way for doing this code?
You've added link to Coding Conventions where seems like actually there is an answer to your question
Unit
If a function returns Unit, the return type should be omitted:
fun foo() { // ": Unit" is omitted here
}
So I believe
fun foo() {}
or
fun foo() {
}
should be the answer