Kotlin higher order function for passing a function to a map - kotlin

I have for example in JS a higher-order function, a function passed to a map:
const numbers = [1, 1, 2, 3, 5, 8]
const transformFunction = x => x + 2
console.log ("transformatio:: ", numbers.map(transformFunction))
If I want to accomplish that in Kotlin, I have:
val numbers = setOf(1, 1, 2, 3, 5, 8)
fun transformFunction (x: Int): Int {
return x + 2
}
println("transformFunction:: ${numbers.map{transformFunction}}")
But Im getting errors:
error: expecting a top level declaration println("transformFunction::
${numbers.map{transformFunction}}")
So what is missing to pass the function to my map operator?

If you pay close attention in that snippet code of js, transformFunction has type function.
So to translate that snippet to Kotlin, declare a variable transformFunction with the type function, too. Then you are good to go
val numbers = setOf(1, 1, 2, 3, 5, 8)
val transformFunction: (Int) -> Int = { it + 2 }
println("transformFunction:: ${numbers.map(transformFunction)}")
The above snippet is the closest translation from JS to Kotlin. But if you want to keep your code the way it is without so many changes, here you are
val numbers = setOf(1, 1, 2, 3, 5, 8)
fun transformFunction (x: Int): Int {
return x + 2
}
println("transformFunction:: ${numbers.map{transformFunction(it)}}")
// or
println("transformFunction:: ${numbers.map(::transformFunction)}")

Related

How can I get the different elements for two List with Kotlin?

I hope to get the different elements in two list, how can I do it with Kotlin?
Such as , the different elements is 9 and 10 in Code A.
Code A
val mutableList1 = mutableListOf(1,2,7,8)
val mutableList2 = mutableListOf(1,2,7,8,9,10)
You could use filterNot:
fun main() {
val mutableList1 = mutableListOf(1, 2, 7, 8)
val mutableList2 = mutableListOf(1, 2, 7, 8, 9, 10)
val differentElements = mutableList2.filterNot { mutableList1.contains(it) }
println(differentElements)
}
Output:
[9, 10]

Is there any operation to multiply each element in the first array to each element in the second array in Kotlin?

Is there any function (like fold, map, filter), which gets 2 arrays and lambda-function (for example multiplication) as parameters and returns third array?
I've used cycle for, but is there more beautiful method?
Yes, there is zip (nice example at the bottom of the page), see this (different) example:
fun main() {
val a = arrayOf( 1, 2, 3, 4 )
val b = arrayOf( 1, 2, 3, 4 )
val c = a.zip(b) { i, j -> i * j }
println(c)
}
which outputs
[1, 4, 9, 16]
There isn't a built in specifically but you can do this:
array1.zip(array2).map { (x,y) -> x*y }

Kotlin Array Slice Indexing

Let's say I want to iterate through all but the first element in Kotlin IntArray. Currently, I'm doing it like this:
fun minimalExample(nums: IntArray): Unit {
for(num in nums.sliceArray(IntRange(1,nums.size-1))) println(num)
}
Is there an easy syntax for doing this like in Python (I don't want to have to specify the ending index of the nums array):
for (num in nums[1:])
I think you could use Kotlin's drop which will remove the first n elements of an array.
fun minimalExampleWithDrop(nums: IntArray): Unit {
for(num in nums.drop(1)) println(num)
}
minimalExampleWithDrop(intArrayOf(1,2,3,4,5,6))
// 2
// 3
// 4
// 5
// 6
Repl.it:
https://repl.it/repls/SvelteShadyLivecd
You can alternatively also use the slice method which is present in lists and arrays. Here are examples for both:
val a = listOf(1, 2, 3, 4)
println(a.slice(1..a.size - 1))
val b = arrayOf(1, 2, 3, 4, 5, 6, 7, 8, 9)
println(b.slice(4..5))
This will print out:
[2, 3, 4]
[5, 6]
A basic for loop with 1 as starting index
val myList = intArrayOf(1,2,3,4,5,6)
for(i in 1 until myList.size){
Log.d(TAG,"${myList[i]}")
}
Or since it's an IntArray you can use it as an Iterator and skip elements like shown here
val iterator = myList.iterator()
// skip an element
if (iterator.hasNext()) {
iterator.next()
}
iterator.forEach {
Log.d(TAG,"it -> $it")
}
Just to add to #gil.fernandes answer, you can use slice with until like this:
val list = arrayOf(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
println(list.slice(0 until 5))
This will output:
[0, 1, 2, 3, 4]

Product of a List or Array in Kotlin

I'm trying to find a way to get the product of a List or Array without using "repeat" or any loop on Kotlin but after some research I couldn't find anything similar.
Something like this in Python would be:
>>> reduce(lambda x, y: x*y, [1,2,3,4,5,6])
output: 720
You can use reduce in Kotlin.
From the doc:
Accumulates value starting with the first element and applying
operation from left to right to current accumulator value and each
element.
val list = listOf<Int>(1, 2, 3, 4, 5, 6)
val array = intArrayOf(1, 2, 3, 4, 5, 6)
list.reduce { acc, i -> acc * i } // returns 720
array.reduce { acc, i -> acc * i } // returns 720
An even simpler solution might be: (1..6).reduce(Int::times)
Use the fold function
val total = listOf(1, 2, 3, 4, 5).fold(1, { total, next -> total * next })
Hope this helps:
fun main(args: Array<String>){
val array = intArrayOf(1, 2, 3, 4, 5, 6)
val product = array.fold(1){acc, i -> acc * i}
println("The result is: $product")
}
This will output the product of the array.
Use the fold or reduce function. Both will work.
val array = arrayOf(1, 2, 3, 4, 5, 6)
println("Product of list: ${listOfMultiplication(array)}")
fun listOfMultiplication(array: Array<Int>): Int {
return array.reduce { total, next -> total * next }
}
val array = arrayOf(1, 2, 3, 4, 5, 6)
println("Product of list: ${listOfMultiplication(array)}")
fun listOfMultiplication(array: Array<Int>): Int {
return array.fold(1) { total, next -> total * next }
}

Unweave sequence, Kotlin functional/streaming idiom

I have a sequence of interleaved data (with fixed stride) and I'd like to reduce it to a single value for each "structure" (n*stride values to n values).
I could just use loop writing into the mutable list with selected step for reader index, but I'm looking for more functional and readable approach. Any thoughts?
For example:
Input sequence consists of RGB triplets (stride 3) and output is grayscale.
Imperative way is like:
fun greyscale(stream:List<Byte>):List<Byte>{
val out = ArrayList(stream.size / 3)
var i = 0; var o = 0
while(i < stream.size)
out[o++]=(stream[i++] + stream[i++] + stream[i++])/3
return out
}
How can I make something like that without explicitly implementing a function and mutable container, but purely on functional extensions like .map and so on?
Kotlin 1.2 (Milestone 1 was released yesterday) brings the chunked method on collections. It chunks up the collection into blocks of a given size. You can use this to implement your function:
fun greyscale(stream: List<Byte>): List<Byte> =
stream.chunked(3)
.map { (it.sum() / 3).toByte() }
A possible way would be grouping by the index of the elements (in this case /3) and mapping these groups to their sum.
stream.withIndex()
.groupBy { it.index / 3 }
.toSortedMap()
.values
.map { (it.sumBy { it.value } / 3).toByte() }
Also strictly functional, but using Rx, would be possible by using window(long)
Observable.from(stream)
.window(3)
.concatMap { it.reduce(Int::plus).toObservable() }
.map { (it / 3).toByte() }
Similar to #marstran's answer, in Kotlin 1.2 you can use chunked function, but providing the transform lambda to it:
fun greyscale(stream: List<Byte>): List<Byte> =
stream.chunked(3) { it.average().toByte() }
This variant has an advantage that it doesn't instantiate a new List for every triple, but rather creates a single List and reuses it during the entire operation.
Excludes remaining elements:
const val N = 3
fun greyscale(stream: List<Byte>) = (0 until stream.size / N)
.map { it * N }
.map { stream.subList(it, it + N).sum() / N }
.map(Int::toByte)
Output
[1, 2, 3, 4, 5, 6] => [2, 5]
[1, 2, 3, 4, 5] => [2]
Includes remaining elements:
const val N = 3
fun greyscale(stream: List<Byte>) = (0 until (stream.size + N - 1) / N)
.map { it * N }
.map { stream.subList(it, minOf(stream.size, it + N)).sum() / N }
.map(Int::toByte)
Output
[1, 2, 3, 4, 5, 6] => [2, 5]
[1, 2, 3, 4, 5] => [2, 3]
Best what I'm capable of is this:
fun grayscale(rgb:List<Byte>):List<Byte>
= rgb.foldIndexed(
IntArray(rgb.size / 3),
{ idx, acc, i ->
acc[idx / 3] = acc[idx / 3] + i; acc
}).map{ (it / 3).toByte() }
Output
in: [1, 2, 3, 4, 5, 6]
out: [2, 5]
And variations with ArrayList with add and last