How to declare mutableListOf of arrays? - kotlin

I want to declare mutableListOf arrays but I don't know how. Google shows me examples like var mutableList1 = mutableListOf<Int>() and etc, but not arrays case(((
import java.util.*
fun main(args: Array<String>) {
var mutableList1 = mutableListOf<Arrays>()
var mutableList2 = mutableListOf(arrayOf<Int>()) //works, but it contains empty array:(
mutableList1.add(arrayOf(1,1)) //error
}

You can do it like this:
val list = mutableListOf<Array<Int>>()
list.add(arrayOf(1, 1))
Edit: As Animesh Sahu (thanks!) has pointed out in the comments, if you don't need boxed integers (no nulls in the arrays), you can use the primitive arrays instead and avoid their overhead:
val list = mutableListOf<IntArray>()
list.add(intArrayOf(1, 1))

You don't need to use mutableListOf
for example
val distributionList = mutableListOf<ParticipantDTO>()
participantVolumeList.forEach {
distributionList.add(
ParticipantDTO(
participantUuid = it.get(PARTICIPANT_VOLUMES.PARTICIPANT_UUID)
)
)
}
better rewrite to
val distributionList = participantVolumeList.map { mapToParticipant(it) }
private fun mapToParticipant(
participantVolumesRec: JParticipantRecord
): ParticipantDTO {
return ParticipantDTO().apply {
participantUuid = participantVolumesRec.get(PARTICIPANT_VOLUMES.PARTICIPANT_UUID)
}
}

Related

How to create a MutableMap with all keys initially set to same value in Kotlin?

I want to create a mutable map whose keys fall in a continuous range, and values initially set to the same value 9 in a single line using Kotlin. How to do that?
One more option not mentioned in the other answers is to use the associate* function that takes the argument collection that it will put the pairs to:
val result = (1..9).associateWithTo(mutableMapOf()) { 9 }
Unlike .associateWith { ... }.toMutableMap(), this doesn't copy the collection.
If you need to use a different implementation (e.g. a HashMap()), you can pass it to this function, like .associateWithTo(HashMap()) { ... }.
Many collection processing functions in the Kotlin standard library follow this pattern and have a counterpart with an additional parameter accepting the collection where the results will be put. For example: map and mapTo, filter and filterTo, associate and associateTo.
If you mean values, you can use the withDefault function on any Map / MutableMap:
(Playground)
fun main() {
val map = mutableMapOf<String, Int>().withDefault { 9 }
map["hello"] = 5
println(map.getValue("hello"))
println(map.getValue("test"))
}
You can try the following:
val map = object : HashMap<Int, Int>() {
init {
(1..10).forEach {
put(it, 9)
}
}
}
println(map)
I would use associateWith:
val map = (1..9).associateWith { 9 }.toMutableMap()
println(map) // {1=9, 2=9, 3=9, 4=9, 5=9, 6=9, 7=9, 8=9, 9=9}
It also works with other types as key, like Char:
val map = ('a'..'z').associateWith { 9 }.toMutableMap()
println(map) // {a=9, b=9, c=9, d=9, e=9, f=9, g=9, h=9, i=9}
You can use the following way:
import java.util.*
fun main(args: Array<String>) {
val a :Int = 0
val b :Int = 7
val myMap = mutableMapOf<IntRange, Int>()
myMap[a..b] = 9
myMap.toMap()
println(myMap) //Output: {0..7=9}
}

Kotlin Creating List<List<Map<String, String>>>

I am trying to return List<List<Map<String, String>>> from a function in kotlin. I'm new to kotlin.
Edit1
Here's how I am attempting to to this
val a = mutableListOf(mutableListOf(mutableMapOf<String, String>()))
The problem with the above variable is, I am unable to figure out how to insert data into this variable. I tried with this:
val a = mutableListOf(mutableListOf(mutableMapOf<String, String>()))
val b = mutableListOf(mutableMapOf<String, String>())
val c = mutableMapOf<String, String>()
c.put("c", "n")
b.add(c)
a.add(b)
This is giving me:
[[{}], [{}, {c=n}]]
What I want is [[{c=n}]]
Can someone tell me how I can insert data into it?
The end goal I am trying to achieve is to store data in the form of List<List<Map<String, String>>>
EDIT 2
The function for which I am trying to write this dat structure:
fun processReport(file: Scanner): MutableList<List<Map<String, String>>> {
val result = mutableListOf<List<Map<String, String>>>()
val columnNames = file.nextLine().split(",")
while (file.hasNext()) {
val record = mutableListOf<Map<String, String>>()
val rowValues = file.nextLine()
.replace(",(?=[^\"]*\"[^\"]*(?:\"[^\"]*\"[^\"]*)*$)".toRegex(), "")
.split(",")
for (i in rowValues.indices) {
record.add(mapOf(columnNames[i] to rowValues[i]))
print(columnNames[i] + " : " + rowValues[i] + " ")
}
result.add(record)
}
return result
}
You don't need to use mutable data structures. You can define it like this:
fun main() {
val a = listOf(listOf(mapOf("c" to "n")))
println(a)
}
Output:
[[{c=n}]]
If you wanted to use mutable data structures and add the data later, you could do it like this:
fun main() {
val map = mutableMapOf<String, String>()
val innerList = mutableListOf<Map<String, String>>()
val outerList = mutableListOf<List<Map<String, String>>>()
map["c"] = "n"
innerList.add(map)
outerList.add(innerList)
println(outerList)
}
The output is the same, although the lists and maps are mutable.
In response to the 2nd edit. Ah, you're parsing a CSV. You shouldn't try to do that yourself, but you should use a library. Here's an example using Apache Commons CSV
fun processReport(file: File): List<List<Map<String, String>>> {
val parser = CSVParser.parse(file, Charset.defaultCharset(), CSVFormat.DEFAULT.withHeader())
return parser.records.map {
it.toMap().entries.map { (k, v) -> mapOf(k to v) }
}
}
For the following CSV:
foo,bar,baz
a,b,c
1,2,3
It produces:
[[{foo=a}, {bar=b}, {baz=c}], [{foo=1}, {bar=2}, {baz=3}]]
Note that you can simplify it further if you're happy returning a list of maps:
fun processReport(file: File): List<Map<String, String>> {
val parser = CSVParser.parse(file, Charset.defaultCharset(), CSVFormat.DEFAULT.withHeader())
return parser.records.map { it.toMap() }
}
Output:
[{foo=a, bar=b, baz=c}, {foo=1, bar=2, baz=3}]
I'm using Charset.defaultCharset() here, but you should change it to whatever character set the CSV is in.

Kotlin/Native: How to convert cArrayPointer to Array

How can I convert cArrayPointer to a simple Array/List when using c-interop?
val myArray: Array<Int> = memScoped {
val cArray = allocArray<IntVar>(5)
fill(cArray)
cArray.toSimpleArray() <--- There is no such function
}
I'd recommend to make it somehow like this:
val myArray: Array<Int> = memScoped {
val length = 5 //cause I don't know how to get C-array size
val cArray = allocArray<IntVar>(length)
(0 until length).map { cArray[it] }.toTypedArray()
}
As one can see in the documentation, CArrayPointer is nothing but a typealias of CPointer. So, I suppose there can't be anadditional functionality, like one you desire.

How to converter list of tuples to tuple of lists?

I have the example to show what I mean:
fun makeRange(i: Int) = Pair(i - 1, i + 1)
val listOfData = listOf(1, 2, 3, 4, 5, 6)
val pairs = listOfData
.map { makeRange(it) }
val leftRange = pairs.map { it.first }
val rightRange = pairs.map { it.second }
I have some list and function which returns a tuple. But the result I need is touple of two lists. I need something like that:
// can I get something like that ?
val (leftRange, rightRange) = listOfData.map { makeRange(it) } ...
Is there a way to do it?
If you really want to destructure it like this, I would also split up your makeRange-function, e.g.:
fun makeLeftRange(i: Int) = i - 1
fun makeRightRange(i: Int) = i + 1
fun makeRange(i: Int) = makeLeftRange(i) to makeRightRange(i) // if you still need it...
Then you can destructure as follows:
val (leftRange, rightRange) = listOfData.map(::makeLeftRange) to listOfData.map(::makeRightRange)
Or if it is really just such an easy function, why not just use the following instead:
val (leftRange, rightRange) = listOfData.map(Int::dec) to listOfData.map(Int::inc)
// or
val (leftRange, rightRange) = listOfData.map { it - 1 } to listOfData.map { it + 1 }
If you want to keep your makeRange as is and want to do it that way, it will get a bit uglier, e.g.:
val (leftRange, rightRange) = listOfData.map(::makeRange).let {
listOfPairs -> listOfPairs.map { it.first } to listOfPairs.map { it.second }
}
Basically reusing what you've shown in an additional let-statement.
Seems like kotlin unzip function is just what you're looking for.
https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/unzip.html
In your example the usage would look something like
val (leftRange, rightRange) = pairs.unzip()

Reading multiple ints from the same line in Kotlin?

I am doing the 30 Days of Code in Kotlin on Hackerrank and I am stuck at Day 7.
How do you read multiple integers on a single line?
How is it added to an array and displayed in reverse?
I have solved it in Java but lack the syntax needed in Kotlin
Input:
4
1 4 3 2
My Code:
fun main(args: Array<String>) {
val n = readLine()!!.toInt()
var arr = Array(n)
for(i in 0 until n)
{
arr[i] = readLine()!!.toInt() //Not Working? nor does readLine()!!.split(' ').toInt()
}
for(item in arr.size - 1 downTo 0)
{
print("${item} ")
}
}
EDIT: question was updated from the original
The problem is the readLine() will read the entire line from stdin, so each time you call readLine() in the for loop it will result in a separate line being read each time.
One approach to this is to read the line, and then to split and map each value to an Int.
readLine()?.let {
val numOfValues = it.toInt()
println(numOfValues)
readLine()?.let { line ->
line.split(" ").map {
it.toInt()
}.reversed().forEach {
println(it)
}
}
}
If you want to store them in a list then you can follow this method
var items = readLine()!!.trim().split("\\s+".toRegex()).map (String::toInt)
println(items)
You can also store them in different variables like this way
var (a,b) = readLine()!!.trim().split("\\s+".toRegex()).map (String::toInt)
println(a+b)
You can also use the following code to item items splited and stored in array for a beginner approach
fun main(ags :Array<String>)
{
var item = readLine()!!.trim()
println(item[0])
}
Actually, you can refer to the official Kotlin tutorial: https://kotlinlang.org/docs/tutorials/competitive-programming.html
as mentioned in tutorial:
To make reading the input in competitive programming tasks like this more concise, you can have the following list of helper input-reading functions:
private fun readLn() = readLine()!! // string line
private fun readInt() = readLn().toInt() // single int
private fun readStrings() = readLn().split(" ") // list of strings
private fun readInts() = readStrings().map { it.toInt() } // list of ints
for your case, you can try use as below:
fun main() {
val n = readInt()
val x = readInts()
for (j in x.reversed()) {
print(j); print(" ")
}
println()
}
private fun readLn() = readLine()!! // string line
private fun readInt() = readLn().toInt() // single int
private fun readStrings() = readLn().split(" ") // list of strings
private fun readInts() = readStrings().map { it.toInt() } // list of ints