Kotlin/Native: How to convert cArrayPointer to Array - kotlin

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.

Related

Kotlin how convert map with long and Pair to other map?

I have a construct like this:
var values = mutableMapOf<Long, Pair<String, Boolean>>()
No I need to have one map from this above like this:
val transformedMap = Map<Long, String>
I cannot transform this first to second. Andy suggestions?
You can do
val transformedMap = values.mapValues { it.value.first }
Most of iterators will require a variable for storing the resulting map, but I think associate can do it directly:
values.entries.associate {
it.key to it.value.first
}
The other options are like this
val output = mutableMapOf<Long, String>()
//values iterator, for, forEach, keys, etc
output[key] = values[key]?.first

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.

How to declare mutableListOf of arrays?

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)
}
}

How to explode a list into a Map in kotlin?

Imagine you want to transform this:
val initialValues: List<Pair<String, String>>
where the first String represents a key, the second a value
into a map:
val finalMap: Map<String,String>
containing each pair item twice, the first with the original key, the second one with a sort of expanded key.
How would you do that? Currently I'm using a
val finalMap = mutableMapOf<String, String>()
that I use while I'm iterating over initialValues. But I really don't like it.
initialValues.forEach {
val explodedPairs:List<Pair<String,String>> = <do-something>
explodedPairs.forEach { finalMap.put(it.first, it.second) }
}
how would you do more assertively?
You can use associate / associateBy like this -
val map1 = initialList.associate { it.first to it.second }
println(map1.toString()) //{1=x, 2=y}
val map2 = initialList.associateBy({it.first},{it.second})
println(map2.toString()) //{1=x, 2=y}
You can also use toMap and do this -
val map3 = initialList.toMap()
println(map3.toString()) //{1=x, 2=y}
where this is my initialList declaration -
val initialList = listOf(Pair(1, "x"), Pair(2, "y"))
You can use associate and associateby
You could use mapOf like this:
val initialValues: List<Pair<String, String>> = listOf()
val final = mapOf(*initialValues.toTypedArray())
But #Supriya has the better answer using toMap