I'm working through a little code challenge in Kotlin.
Write a function that nests the elements of a list one level deeper by repeating that
element inside a new list a given number of times.
Examples
(nest [:a :b :c] 2) ;=> ((:a :a) (:b :b) (:c :c))
(nest [] 10) ;=> ()
(nest [1 2 3 4] 1) ;=> ((1) (2) (3) (4))
(nest [1 2 3] 0) ;=> (()()())
I implemented nest like so:
fun <R> nest(list: List<R>, repeat: Int) =
list.map{
mem -> generateSequence(1) { it }
.map { mem }
.take(repeat)
.toList()
}
However, I'm wondering how I'd write the lambda as a separate anonymous function, which I'd pass to map, like...
val anonFunction = ???
list.map(anonFunction)
I'm not sure how this would work syntactically.
Curly braces is what starts a lambda function in Kotlin. The only thing you need to do to assign an arbitary lambda to a val, is to let Kotlin know what type it has.
This is probably the simplest way to do it. I am giving the compiler the type of the parameter, but letting type inference take care of the return type.
fun <R> nest(list: List<R>, repeat: Int): List<List<R>> {
val anonFunction = { mem: R ->
generateSequence(1) { it }
.map { mem }
.take(repeat)
.toList()
}
return list.map(anonFunction)
}
You could also do it by specifying the full function type of anonFunction by declaring it like this:
fun <R> nest(list: List<R>, repeat: Int): List<List<R>> {
val anonFunction: (R) -> List<R> = { mem ->
generateSequence(1) { it }
.map { mem }
.take(repeat)
.toList()
}
return list.map(anonFunction)
}
Side note:
A simpler implementation of your challenge could be this:
fun <R> nest(list: List<R>, repeat: Int) = list.map { elem ->
List(repeat) { elem }
}
Related
Does Kotlin have something to filter a collection and return the matching indexes?
E.g. like Groovy's findIndexValues:
http://docs.groovy-lang.org/latest/html/groovy-jdk/java/lang/Iterable.html#findIndexValues(groovy.lang.Closure)
Something like:
fun <T> List<T>.findIndexValues(predicate: (T) -> Boolean): List<Int> {
var indexValues = mutableListOf<Int>()
this.forEachIndexed { index, it ->
if (predicate(it)) {
indexValues.add(index)
}
}
return indexValues
}
The simplest way I can think of to do this is to use mapIndexedNotNull:
fun <T> List<T>.findIndexValues(predicate: (T) -> Boolean): List<Int> =
mapIndexedNotNull { i, t -> i.takeIf { predicate(t) } }
I don't believe there's a function for this in the standard library.
There are basically 2 simple ways according to me.
//say there is a List x of Strings
val x = listOf<String>()
//I don't believe you are looking for this.
//string is the required String of x at index.
for ((index, string) in x.withIndex()) {
TODO()
}
//2nd method is using filterIndexed
/**
* Returns a list containing only elements matching the given predicate.
* #Params: predicate - function that takes the index of an element and the element itself and returns the result of predicate evaluation on the element.
*/
x.filterIndexed { index, string ->
TODO()
}
I like #Sam's answer, but I find this implementation to be slightly more readable as it filters explicitly on predicate as opposed to implicitly via null:
fun <T> List<T>.findIndexValues(predicate: (T) -> Boolean): List<Int> =
withIndex().filter { (_, t) -> predicate(t) }.map { it.index }
Having seen flatten, I was looking for something that would be a deepFlatten, i.e., it would work with not only Iterable<Iterable<T>> (it's pretty much the same for Arrays, but let's focus on Iterable now for brevity), but also with Iterable<Iterable<Iterable<T>>>, Iterable<Iterable<Iterable<Iterable<T>>>> and so on...
Of course, the result would have to be List<T>, which the standard flatten() doesn't provide - it would return List<Iterable<T> (or a List with more nested Iterables).
I was trying to work with reified generics:
inline fun <reified E, T> Iterable<E>.deepFlatten(): List<T> = when(E::class) {
Iterable<*>::class -> (this as Iterable<Iterable<*>>).flatten().deepFlatten()
else -> flatten()
}
But this obviously is flooded with errors:
T seems pretty undeducible
You cannot have a ::class of an interface
You cannot recurse on an inline function
Are there any workarounds on the above problems? Or, even better, is there a cleaner approach to the problem?
To demonstrate an example for completeness, I'd like to be able to do:
fun main() {
val data: List<List<List<Int>>> = listOf(
listOf(listOf(1, 2, 3), listOf(5, 6), listOf(7)),
listOf(listOf(8, 9), listOf(10, 11, 12, 13))
)
print(data.deepFlatten()) // 1 2 3 4 5 6 7 8 9 10 11 12 13
}
The depth of nested Iterables (they need not be the same type - it's important that they are generically Iterable) can vary.
In Java, you might achieve the very same behavior using java-stream:
Using Collection<?>:
public static Stream<?> deepFlatMap(Object o) {
if (o instanceof Collection<?>) {
return ((Collection<?>) o).stream().flatMap(i -> deepFlatMap(i));
}
return Stream.of(o);
}
Using Iterable<?>:
public static Stream<?> deepFlatMap(Object o) {
if (o instanceof Iterable<?>) {
Spliterator<?> spliterator = ((Iterable<?>) o).spliterator();
return StreamSupport.stream(spliterator, false).flatMap(i -> deepFlatMap(i));
}
return Stream.of(o);
}
The usage is pretty straightforward: deepFlatMap(list).forEach(System.out::println);
As long as I don't know Kotlin, I hope this can at least help you with rewriting the idea.
Edit: As long as you want to specify the return target generic type, you should use another wrapper method (don't forget to change the name in the recursive method):
public static <T> Stream<T> deepFlatMap(Collection<?> collection) {
return (Stream<T>) internalDeepFlatMap(collection);
}
public static Stream<?> internalDeepFlatMap(Object o) {
if (o instanceof Collection<?>) {
return ((Collection<?>) o).stream().flatMap(i -> internalDeepFlatMap(i));
}
return Stream.of(o);
}
Usage with specifying the generic type explicitly:
MyClass.<Integer>deepFlatMap(list).map(i -> i + 1).forEach(System.out::println);
fun <T> Iterable<*>.deepFlatten(): List<T> {
val result = ArrayList<T>()
for (element in this) {
when (element) {
is Iterable<*> -> result.addAll(element.deepFlatten())
else -> result.add(element as T)
}
}
return result
}
...
println(data.deepFlatten<Int>())
You have to specify the type explicitly and you lose compile-time safety. But it can flatten lists of any nesting and with elements of different types ([1, "foo", [3, "bar"]] -> [ 1, "foo", 3, "bar"])
I would prefer a different solution. Something like this:
typealias It2<T> = Iterable<Iterable<T>>
typealias It3<T> = Iterable<It2<T>>
typealias It4<T> = Iterable<It3<T>>
typealias It5<T> = Iterable<It4<T>>
//etc...
fun <T> It3<T>.flatten2(): List<T> = flatten().flatten()
fun <T> It4<T>.flatten3(): List<T> = flatten2().flatten()
fun <T> It5<T>.flatten4(): List<T> = flatten3().flatten()
//etc...
...
println(data.flatten2())
I have an array of classes with values. E.g.
class MyData(val value: Double)
class MyClass(val values: List<MyData>)
it's pretty easy to get the sum of all values in the array:
values.sumByDouble { it.value }
Is there an equivalent to multiply these values inside those classes?
You can create an extension function:
public inline fun <T> Iterable<T>.multiplyByDouble(selector: (T) -> Double): Double {
this.firstOrNull() ?: return 0.0
var result = 1.0
for (element in this) {
result *= selector(element)
}
return result
}
and use it:
listOf(2.0, 3.0).multiplyByDouble { it } // 6.0
listOf<Double>().multiplyByDouble { it } // 0.0
There is no dedicated function for that, but you can use reduce for that. But there is a problem. Since the element (in this case of type T with S as upper bound) has to be a subtype of the accumulator (in this case of type S),
inline fun <S, T : S> Iterable<T>.reduce(
operation: (acc: S, T) -> S
): S
which is not the case in your example, it would be a good idea to first map the MyData elements to the Double value:
val l = listOf(MyData(1.0), MyData(2.0), MyData(3.0))
.map { it.value }
.reduce { acc, ele -> acc * ele }
println(l) // 6.0
Alternatively, you could change your data model (like shown here) but that might not be a good idea just for the sake of multiplying all values, but it depends on your use-case.
In Kotlin, it is possible to write
class A {
fun B.foo()
}
and then e.g. write with (myA) { myB.foo() }.
Is it possible to write this as an extension method on A, instead? My use case is writing
with (java.math.RoundingMode.CEILING) { 1 / 2 }
which I would want to return 1, the point being that I want to add operator fun Int.div(Int) to RoundingMode.
No it's not possible. operator div is required to have Int as a receiver.
You can't add also RoundingMode as receiver, since there can only be single function receiver.
What you can do, though, is use Pair<RoundingMode, Int> as a receiver:
operator fun Pair<RoundingMode, Int>.div(i: Int): BigDecimal =
BigDecimal.valueOf(second.toLong()).divide(BigDecimal.valueOf(i.toLong()), first)
with(RoundingMode.CEILING) {
println((this to 1) / 2) // => 1
}
That's not possible, Int already has a div function, thus, if you decide to write an extension function div, you won't be able to apply it, because member functions win over extension functions.
You can write this though:
fun RoundingMode.div(x: Int, y: Int): Int {
return if (this == RoundingMode.CEILING) {
Math.ceil(x.toDouble() / y.toDouble()).toInt()
} else {
Math.floor(x.toDouble() / y.toDouble()).toInt()
}
}
fun main(args: Array<String>) {
with(java.math.RoundingMode.CEILING) {
println(div(1,2))
}
}
It's not possible for a couple of reasons:
There's no "double extension functions" concept in Kotlin
You can't override a method with extension functions, and operator div is already defined in Int
However you can workaround these issues with
A context class and an extension lambda (e.g. block: ContextClass.() -> Unit)
Infix functions (e.g. use 15 div 4 instead of 15 / 4)
See the example below:
class RoundingContext(private val roundingMode: RoundingMode) {
infix fun Int.div(b: Int): Int {
val x = this.toBigDecimal()
val y = b.toBigDecimal()
val res = x.divide(y, roundingMode)
return res.toInt()
}
}
fun <T> using(roundingMode: RoundingMode, block: RoundingContext.() -> T): T {
return with(RoundingContext(roundingMode)) {
block()
}
}
// Test
fun main(args: Array<String>) {
using(RoundingMode.FLOOR) {
println(5 div 2) // 2
}
val x = using(RoundingMode.CEILING) {
10 div 3
}
println(x) // 4
}
Hope it helps!
This declaration works, but is not the most beautiful code. Is there a way to return functions less ugly? I tried (s: String) -> writer.println(s) but this didn't work.
val writeStuff: (PrintWriter) -> (String) -> Unit = {
val writer = it
val f: (String) -> Unit = {
writer.println(it)
}
f
}
PrintWriter("test").use { writeStuff(it)("TEST") }
EDIT: a bit more concrete example:
val writeStuff: (PrintWriter) -> (String) -> Unit = { writer ->
{ writer.println(it) }
}
val sendStuff: (Any) -> (String) -> Unit = { sender ->
{ sender.equals(it) }
}
#Test fun test1() {
val li = listOf("a", "b", "c")
val process: List<(String) -> Unit> =
listOf(writeStuff(PrintWriter("a")), sendStuff(Object()))
process.map { li.map(it) }
}
First, you can simplify your code using lambda syntax with explicit parameter and inlining val f:
val writeStuff: (PrintWriter) -> (String) -> Unit = { writer ->
{ writer.println(it) }
}
But since Kotlin supports local function declarations, you can even make writeStuff a local fun instead of a val.
This would lead to the following code:
fun writeStuff(writer: PrintWriter): (String) -> Unit {
return { writer.println(it) }
}
Or, using the single expression syntax,
fun writeStuff(writer: PrintWriter): (String) -> Unit = { writer.println(it) }
The usage, however, will be the same:
PrintWriter("...").use { writeStuff(it)("...") }
I stumbled across this question while trying to figure out how to return a Function (the java interface) in Kotlin. While this doesn't directly answer the question, hopefully it'll help someone else who has the same query:
override fun myFun(param1: Object): Function<in Object, out String?> {
if (!param1.meetsCriteria())
return Function { obj -> null }
return Function { obj ->
"success"
}
}
In this case, I was overriding a method in a java interface that required me to return a Function instance. (Note that since the param is not used in my particular implementation above, I could remove it and just have the return result. eg return Function { null })
Edit: After some research, it turns out Kotlin covers this subject with their discussion on "SAM (single abstract method) conversions" here and here, though it may not be the most intuitive thing to look up when figuring out how to return Functions.