How to initiate array items using for loop in Kotlin - kotlin

Python allows programmers to perform such an operation:
mylist = [1, 2]
items = [value * 2 for value in namelist]
How can I achieve the same using Kotlin, I want to pass values multiplied by 2 from mylist into the array below:
val mylist = mutableListOf(1, 2)
val (first, second) = arrayOf( )
Kotlin allows us to to declare and initiate variables with one liners as below
val (first, second) = arrayOf(1, 2) that way you can call first or second as a variable. Am trying to make the equal part dynamic

Equivalent of the above Python code in Kotlin is:
val mylist = listOf(1, 2)
val items = mylist.map { it * 2 }
If you need to assign resulting doubled values to first and second, then do it exactly as you did:
val (first, second) = mylist.map { it * 2 }
You need to be sure myList contains at least 2 items.

Try this out:
// === KOTLIN
var mylist = listOf(1, 2)
val result = mylist.map { it * 2 }
println(result)
// output: [ 2,4 ]

Related

Kotlin how apply different functions by predictor

I need to apply 2 different functions to my list in Kotlin based on external map, saving initial order of the list.
class Example(){
val mapper = mapOf<String, Int>(
"abc" to 1,
"de" to 0,
"fedd" to 1,
"q" to 1
)
fun function1(x:String)=x.length*2
fun function0(x:String)=x.length*3
fun function(lst: List<String>){
TODO("Need to apply function1 for all values in dictionary, where corresponding value in mapper is 1" +
"And apply function 0 for all values where corresponding value in mapper is 0")
}
}
So, for list ["q", "fedd", "de"] method Example.function() should return [2, 8, 6]
2 -> q value in mapper is 1, applying function1, multiplying by 2, get 1*2=2
8 -> fedd in mapper is 1, applying function1, multiplying by 2, get 4*2=8
6 -> de in mapper is 0, applying function0, multiplying by 3, get 2*3=6
What is the easiest way to realise this logic?
You could use map on the list to achieve this. follow below:
val mapper = mapOf<String, Int>(
"abc" to 1,
"de" to 0,
"fedd" to 1,
"q" to 1
)
fun function1(x: String) = x.length * 2
fun function0(x: String) = x.length * 3
fun function(lst: List<String>) {
val newList = lst.map {
when (mapper[it]) {
0 -> function0(it)
1 -> function1(it)
else -> error("Key doesn't exist in map, throw or return value as is.")
}
}
}

Convert a List of Integers to List of String in Kotlin

I have a List like [1,2,3,4,5] and I am trying to convert to List ["1","2","3","4","5"]
I tried doing it like this
val numbers = listOf(1, 2, 3, 4, 5)
val numbersStr = mutableListOf<String>()
val itr = numbers.listIterator()
while(itr.hasNext())
{
numbersStr.add(itr.next().toString())
}
but I feel it is little verbose and doesnt make use of Kotlin's built in functions.
What is the best alternative?
Check out kotlin's map function
val numberStr = listOf(1, 2, 3, 4, 5).map { it.toString() }

How do I sum all the items of a list of integers in Kotlin?

I have a list of integers, like:
val myList = listOf(3,4,2)
Is there any quick way in Kotlin to sum all the values of the list? or do I have to use a loop?
Thanks.
You can use the .sum() function to sum all the elements in an array or collection of Byte, Short, Int, Long, Float or Double. (docs)
For example:
val myIntList = listOf(3, 4, 2)
myIntList.sum() // = 9
val myDoubleList = listOf(3.2, 4.1, 2.0)
myDoubleList.sum() // = 9.3
If the number you want to sum is inside an object, you can use sumOf to select the specific field you want to sum: (docs)
data class Product(val name: String, val price: Int)
val products = listOf(Product("1", 26), Product("2", 44))
val totalCost = products.sumOf { it.price } // = 70
Note: sumBy was deprecated in Kotlin 1.5 in favour of sumOf.
The above answer is correct, as an added answer, if you want to sum some property or perform some action you can use sumBy like this:
sum property:
data class test(val id: Int)
val myTestList = listOf(test(1), test(2),test(3))
val ids = myTestList.sumBy{ it.id } //ids will be 6
sum with an action
val myList = listOf(1,2,3,4,5,6,7,8,9,10)
val addedOne = myList.sumBy { it + 1 } //addedOne will be 65
The above answers are correct but, this can be another way if you also want to sum all integers, double, float inside a list of Objects
list.map { it.duration }.sum()
sumBy is Deprecated new use sumOf instead
val data = listOf(listOf(1, 2, 3), listOf(4, 5, 6))
println(data.sumOf { it.size }) // 6
println(data.sumOf { innerList -> innerList.sumOf { it } }) //21
println(data.sumOf { innerList -> innerList.sum() }) // 21

How to copy the text from File into arraylist or map in Kotlin

var writer = PrintWriter("abc.txt")
writer.println("John")
writer.println("Emmy")
writer.println("Char")
writer.close()
var reader = File("abc.txt")
reader.forEachLine { println(it) }
but how can I store these names into map like john should be key and Emmy should be value
You almost have it:
val list = arrayListOf<String>()
val mapNames = hashMapOf<String, String>()
val reader = File("abc.txt")
reader.forEachLine { list.add(it) }
for (i in 1..list.size / 2) {
val key = list[2 * i - 2]
val value = list[2 * i - 1]
mapNames.put(key, value)
}
An alternative would be to use a more functional approach.
val writer = PrintWriter("abc.txt")
writer.println("John")
writer.println("Emmy")
writer.println("Char")
writer.close()
val reader = File("abc.txt")
val mapTruncated = reader.readLines().windowed(2, 2) {
it[0] to it[1]
}.toMap()
-> {John=Emmy}
readLines() creates an List<String> that conatins all lines.
windowed(2, 2) iterates over this list and visits 2 elements for each iteration. After an iteration it increases the current index by 2. This will truncate the last line if it's not a full window (No value for the given key).
The lambda transforamtion { it[0] to it[1] } converts the window of type List<String> to an Pair<String, String>.
The resulting list (List<Pair<String, String>>) can be transformed to a map with toMap().
If you want all lines and fill the last key with eg. null you cann do something like this.
val mapComplete = reader.readLines().chunked(2) {
it[0] to it.getOrNull(1)
}.toMap()
-> {John=Emmy, Char=null}
chunked(2) is an alias for windowed(2, 2, true). The last param true means it should include partial windows.

Zip 3 lists of equal length

Is there a standard operation in Kotlin stdlib which would allow to iterate over a zip of 3 (or more) lists?
Effectively it should do:
list1.zip(list2).zip(list3) { (a, b), c -> listOf(a, b, c)}
Here are functions in the style of the standard library that do this. I'm not saying these are particularly optimized, but I think they're at least easy to understand.
/**
* Returns a list of lists, each built from elements of all lists with the same indexes.
* Output has length of shortest input list.
*/
public inline fun <T> zip(vararg lists: List<T>): List<List<T>> {
return zip(*lists, transform = { it })
}
/**
* Returns a list of values built from elements of all lists with same indexes using provided [transform].
* Output has length of shortest input list.
*/
public inline fun <T, V> zip(vararg lists: List<T>, transform: (List<T>) -> V): List<V> {
val minSize = lists.map(List<T>::size).min() ?: return emptyList()
val list = ArrayList<V>(minSize)
val iterators = lists.map { it.iterator() }
var i = 0
while (i < minSize) {
list.add(transform(iterators.map { it.next() }))
i++
}
return list
}
Usage:
val list1 = listOf(1, 2, 3, 4)
val list2 = listOf(5, 6)
val list3 = listOf(7, 8, 9)
println(zip(list1, list2, list3)) // [[1, 5, 7], [2, 6, 8]]