I was using the removeAt function and it was just working fine but then suddenly the compiler started to throw the error unresolved reference : removeAt
Here is the code:
fun main() {
val nums = mutableListOf(-3, 167, 0, 9, 212, 3, 5, 665, 5, 8) // this is just a list
var newList = nums.sorted() // this is the sorted list
var finall = mutableListOf<Int>() // this is an empty list that will contain all the removed elements
for(i in 1..3) {
var min: Int = newList.removeAt(0) // element removed from newList is saved from min variable
// above line is producing the error
finall.add(min) // then the min variable is added to the empty list created before
}
println(finall)
println(newList)
}
I have studied a bunch of documentries but I'm unable to find my mistake
The 3rd line, where you sort the list, returns a list not a mutableList. So newList is non-mutable. Replacing that 3rd line with var newList = nums.sorted().toMutableList() will make newList mutable and solve your problem.
The result of nums.sorted() is an immutable list, which means you cannot change it, or in other words, remove elements.
You need to tell kotlin you want a mutable list var newList = nums.sorted().toMutableList()
because newList is List object. List object no method removeAt
you need using newList.toMutableList().removeAt()
Related
I have a data class in Kotlin like this:
data class Activity(
var id: String? = "",
var prize: MutableMap<String?, Int?>? = null
)
And a list of this object:
var myList = listOf(Activity("A", prize={day_5=70, day_4=70}),
Activity("B", prize={day_5=40, day_4=80}))
The desired result is:
Activity("A", prize={total=140}),
Activity("B", prize={total=120})
So basically I want to sum the values of the prize map inside of each object.
I think that has something to do with transformation but I'm new to Kotlin and I couldn't find any resources over the internet, or maybe they were to complicated.
This algorithm is easy, just iterating through all the maps and replace elements with the sum:
val myList = listOf(
Activity("A", hashMapOf("day_5" to 70, "day_4" to 70)),
Activity("B", hashMapOf("day_5" to 40, "day_4" to 80)),
)
for (i in myList) {
val total = i.prize.values.sum()
i.prize.clear()
i.prize["total"] = total
}
I need to check if the certain value exists in both arrays and if exists remove this element from the second array. I know that it exists.
taking the 1st element from array doubleTue, taking the index where is this value in amTue and pmTue then remove those by using splice command.
But now my code is having problem on getting the first value.
tried as in level array: var val = doubleTue[i]
and 2 level array: var val - doubleTue[i][0]
tried toString(), read()
for (var n=0; n<doubleTue.length; n++)
{
var val = doubleTue[i][0];
var val1 = amTue.indexOf(val);
if (val1!=-1) {amTue.splice(val1, 1);};
var val2=pmTue.indexOf(val);
if (val2!=-1) {pmTue.splice(val2, 1); };
}
}
the issue is found. i have used wrong variable for looping. hehe. copy past issue
thnks all
I often end up with data sources like (pseudo code below, not any specific syntax, it is just to illustrate):
list = {
"XLabel",
"XDescription",
"YLabel",
"YDescription",
"ZLabel",
"ZDescription"
}
desired output is:
list = {
MyClass("XLabel", "XDescription"),
MyClass("YLabel", "YDescription"),
MyClass("ZLabel", "ZDescription")
}
Is there anything more clean than to do a fold(), and fold it into a new list? I've also rejected doing something weird like list.partition().zip()
I basically want a more powerfull map that would work like mapChunks( it1, it2 -> MyClass(it1, it2)) where the chunking is part of the function so it gets easy and nice. (My example has the list in chunks of two, but 3 is also a prevalent use case.)
Does this function exist? Or what is the most idiomatic way to do this?
You can use the chunked function, and then map over the result. The syntax gets very close to what you wanted if you destructure the lambda-argument:
list.chunked(2)
.map { (it1, it2) -> MyClass(it1, it2) }
// Or use _it_ directly: .map { MyClass(it[0], it[1]) }
I think the windowed method should do what you want.
lst.windowed(size = 2, step = 2, partialWindows = false) { innerList -> MyClass(innerList[0], innerList[1]) }
You can also use chunked but it calls windowed under the hood. But with chunked you can get lists that have fewer elements than you were expecting
EDIT to answer #android developer's question about getting the indexes of the list
val lst = listOf(7, 8, 9, 10, 11, 12, 13, 14, 15, 16)
val windowedList = lst.mapIndexed { index, it -> index to it }
.windowed(size = 2, step = 2, partialWindows = false) {
it[0].first
}
println(windowedList)
Would output
[0, 2, 4, 6, 8]
To add to the existing answers, you can use chunked function with the transform lambda passed as its second argument:
list.chunked(2) { (label, description) -> MyClass(label, description) }
This way is more efficient because the temporary list of two elements is reused across all chunks.
You can create an extension function, for example mapChunks, and reuse it:
fun List<String>.mapChunks(): List<MyClass> {
return chunked(2).map { MyClass(it[0], it[1]) }
}
val list1 = listOf(
"XLabel",
"XDescription",
"YLabel",
"YDescription",
"ZLabel",
"ZDescription"
)
val result1 = list1.mapChunks()
val list2 = listOf(
"XLabel1",
"XDescription1",
"YLabel1",
"YDescription1",
"ZLabel1",
"ZDescription1"
)
val result2 = list2.mapChunks()
https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/chunked.html
Chunked returns a sub list of the size you specify
This is the API call you want
considering your list is in pairs of 2 you can do this
list.chunked(2) //List<List<String>>
.map{MyClass(it[0], it[1]} //list<MyClass>
In Kotlin, how can I take the first n elements of this array:
val allColours = arrayOf(
Pair(Color.RED, Color.WHITE),
Pair(Color.RED, Color.BLACK),
Pair(Color.YELLOW, Color.BLACK),
Pair(Color.GREEN, Color.WHITE),
Pair(Color.BLUE, Color.WHITE),
Pair(Color.BLUE, Color.WHITE),
Pair(Color.CYAN, Color.BLACK),
Pair(Color.WHITE, Color.BLACK))
So how can I fill pegColours with the first say 3 Pairs?
var pegColours: Array<Pair<Color,Color>> = //???
I tried allColours.take but it gave an error:
Expecting an element
You need to specify the number of items you want to take.
allColours.take(3)
For a random number of random indices, you can use the following:
val indexes = arrayOf(2, 4, 6)
allColours.filterIndexed { index, s -> indexes.contains(index) }
Note that you can write an extension method for this:
fun <T> Array<T>.filterByIndices(vararg indices: Int) = filterIndexed { index, _ -> indices.contains(index) }
Alternatively, if the indices are consecutive, you can use slice:
allColours.slice(1..3)
The problem with your code that you create pairs with color constants which are Ints (allColours has type Array<Pair<Int, Int>>), but you expect Array<Pair<Color, Color>>. What you have to do is change type pegColours type and use take:
var pegColours: Array<Pair<Int, Int>> = allColours.take(3).toTypedArray()
Also you have to call toTypedArray() cause Array.take returns List rather than Array. Or you can change pegColours type as following:
var pegColours: List<Pair<Int, Int>> = allColours.take(3)
I know you already proposed the usage of take, but alternatively ranges and a simple map also help to write idiomatic code as shown next:
var pegColours = (0 until 3)
.map { allColours[it] }
.toTypedArray()
You are very close :)
val allColours = arrayOf("red", "blue", "green")
kotlin.io.println(allColours.take(2))
Will give you first two elements ["red", "blue"]
You have to specify the number of elements you want to take from the array
I'm trying to copy first 2 elements of my firstArray to my secondArray.
var firstArray = arrayListOf(1,2,3,4)
var secondArray = firstArray.copyOfRange(0,1)
However I'm getting "unsolved reference" error in copyOfRange for some reason.
If I define an Array type for my firstArray I can solve the problem but I don't want to because it can contain different variables in future
The arrayListOf function returns an ArrayList. If this is what you want to use, then you should use the subList function on it:
val firstList = arrayListOf(1, 2, 3, 4)
val secondList = firstList.subList(0, 1)
Note that subList doesn't create a copy, you can make a copy with a toList call, for example:
val secondList = firstList.subList(0, 1).toList()
Or with an explicit call to the ArrayList constructor:
val secondList = ArrayList(firstArray.subList(0,1))
If you want to use an Array instead, use arrayOf and then you can use copyOfRange:
val firstArray = arrayOf(1, 2, 3, 4)
val secondArray = firstArray.copyOfRange(0, 1)