How to feed a nested collection in Kotlin? - kotlin

Here is the code:
var list = mutableListOf<Set<String>>()
list[0] = mutableSetOf("bar")
list[0].add("foo") // doesn't compile
Why it doesn't compile ?
And how can I add an element to a nested collection ?

This is because you have set the element type of the mutable list as Set, which is immutable.
You should specify that it has a mutable set, for example: mutableListOf<MutableSet<String>>

Related

Dynamically add list to a list in Kotlin

I have:
var myList: MutableList<MutableList<Int>>
and I want to dynamically create a list (i, j) which are Int and it is to the myList.
I tried
myList.add(mutableListOf(i,j))
But it doesn't work.
Firstly I get error: variable 'myList' must be initialized
And I am not sure that's the right way to make a list on the go and add it to a list of lists
As the error mentions, you have to initialize the list before using it.
var myList: MutableList<MutableList<Int>> with this you just declare its type.
var myList = mutableListOf<MutableList<Int>>() with this you have empty list. After that you can freely add another list inside it as an element.
initialize the list
var myList: MutableList<Int> = ArrayList()

How to initialize List< List<Int> > in Kotlin?

As per leetcode question here I am required to return List<List<Int>> type for Kotlin submission.
I tried using listOf() but unable to create.
My another guess was to use LinkedList of type List:
var result: List<List<Int>> = LinkedList<List<Int>>()
The intelliJ idea gives no warnings for the above declaration but add() is not available on result variable. Please let me know what I am doing wrong.
How should I initialize empty List<List<Int>> type in kotlin?
add is not available for List. It's available for MutableList. LinkedList is a MutableList, but you are upcasting it to a plain List by assigning it to a variable of type List.
If you need to work with a MutableList or LinkedList inside this function, you can do so by not declaring the type of the result variable so it will implicitly be a MutableList or LinkedList. When you return it from the function, it will be implicitly upcast at that time, when you no longer need the mutable features.
fun threeSum(nums: IntArray): List<List<Int>> {
val output = mutableListOf<MutableList<Int>>()
// logic
return output
}
or
fun threeSum(nums: IntArray): List<List<Int>> {
val output = LinkedList<LinkedList<Int>>()
// logic
return output
}
LinkedList is a specific type of MutableList that compared to the default MutableList (ArrayList) is heavier and slower at accessing specific elements in the middle, but faster at accessing elements at the start/end and faster at inserting or removing elements. You will most commonly just want to use mutableListOf to instantiate mutable lists.
you can use
var result: List<List<Int>> = listOf(listOf())
or
var result = listOf(listOf<Int>())

Kotlin: Should mutableList be declared as Val or Var?

I am reading through the existing codebase for my team, and I notice mutableListOf are always declared as val. In some scenarios, elements are added to the mutableListOf only once. E.g
val jobList = mutableListOf<JobActivity>()
jobList.addAll(job.activities)
In other scenarios, elements are added to mutableListOf in a loop. E.g
val jobList = mutableListOf<JobActivity>()
newJobList.filterScanType(retrieveJobType(JobContext.NEW)).forEach {
jobList.add(it)
}
Since the list is not initialized on creation, why not declare mutableListOf as var? A lot of examples found online also follow the same pattern of declaring mutableListOf as val.
Which is best to use in the 2 scenarios described, val or var?
I think it's declared as val because the list will be the same always, the only thing that changes is it's elements. You'll never do something like:
joblist = anotherList
And as #Taseer said, the properties of the object can be changed even if it's a val. For example:
data class Example(var name: String)
val exampleObject = Example("SomeName")
You'll still be able to do this:
exampleObject.name = "AnotherName"
But you can't do this:
exampleObject = anotherObject
The general rule of thumb while using Kotlin.
Difference in val and var
You may already know the differences but for the sake of an answer, I will repeat it. var lets you modify the reference of an object while val does not permit to change the reference of an object.
An object can be declared safely using either var or val keyword but the reason why you want to use val on an object(in most cases) is that you don't want to refer that class member with a new reference of a new instance of an object. That way, you always keep a reference to the original object and you can modify object properties.
In the case of var, though nothing wrong with it, you can still use it 'without' any problems. You can still access the object properties and modify them and also you will be able to refer that class member to a reference of a new object.
Example:
val myObject = MyObject()
myObject.something = 1 //can still modify object property.
myOjbect = MyObject() //re-referencing the object, NOT POSSIBLE
var myNewObject = MyNewObject()
myNewObject.someThing = "Hello world!" //can still modify object properties
myNewObject = MyNewObject() //can still reference it.
Why to use val over var in case of 'immutable' objects?
It gives you the security of not 'accidentally' placing a new reference.
But is there any performance benefit using val?
Answer: Final keyword benefit
val is more idiomatic for the reasons given in other answers and comments.
You said the val is not instantiated, but in your example code, it is.
val jobList = mutableListOf<JobActivity>()
is a factory that instantiates an empty MutableList<JobActivity>
Using this pattern (val not var, instantiated upon declaration) ensures that your code will never find an uninitialized or null value for jobList; and the compiler can prove it.
In short - there are no rules, its up to you
if you use val you can modify mutableList, but not reassign
if you need reassign another list to same variable, use var. In most cases you dont need it, thats why your team uses it frequently
Whether a variable is var or val distinguishes between a variable of which the value (reference) can be changed (var = mutable) or not (val = immutable).
You should always strive to use val over var to avoid unwanted side-effects (changing it in another thread for example).
In case of the MutableList you should most likely use a val, because you don't want to mutate the reference to the list but rather its contents.
Here an overview of your options:
// Do you want to change its reference (r) / contents (c)?
var a = mutableListOf(1, 2, 3) // r = yes, c = yes
var b = listOf(1, 2, 3) // r = yes, c = no
val c = mutableListOf(1, 2, 3) // r = no, c = yes
val d = listOf(1, 2, 3) // r = no, c = no
You create a variable with var that is mutable (that can change). Mutable means variable can be changed in future.
val is used when variable will not be changed in future that means constant or final.
Here changed means new value or new things will be assigned to the variable but
val list = mutableListOf()
in this list variable you assigned mutable list. You just changed the value of the list. But you didn't assign new instance or new value to the variable you just added and remove value from the list. That's it. So here list is immutable itself.
It will be mutable if you do things like below...
var list = mutableListOf()
list = mutableListOf()
Two initialization on the same variable.

sortedBy() selector not sorting List

I have a sortedBy{} statement which intends to sort a List by the length of the String elements:
var animals: List<String> = listOf("tiger", "cat", "dragon", "elephant")
fun strLength(it: String) = it.length
animals.sortedBy { strLength(it) }
animals.forEach {println(it)}
However it only prints the initial order. Any idea why?
You have to assign the output of sortedBy.
animals = animals.sortedBy { strLength(it) }
Because, like many other functions in Kotlin, sortedBy doesn’t mutate the input & honour immutability. So it returns a new collection. So it mitigates side-effects. Kotlin encourages this immutable approach. However, there are mutable counterparts of these collections if required.
sortedBy does not sort the list, instead it returns a new list which has the elements sorted. If you don't want a new list, simply use sortBy.

pushing items to array in typescript in a structured way

I have these items here that I want to push to an array in a set format.
I have declared my array this way
finalCount = [];
Now I want this array to have items in this format:
animal: Count
For e.g:
dog: 3
cat: 4
cow: 1
And each item in the array should be accessible by providing a index number as well. for e.g finalCount[0] should pick dog.
I tried to push items this way
this.finalCount.push(this.animal, this.count);
but each item here doesn't go together.
How do I get that.
To push items in your final count array, you can leverage synthax originally introduced with ES2015, computed properties
Now if you want to define the TypeScript type for objects in the finalCount array. You should create the following interface:
interface FinalCountItem {
[animal: string]: number;
}
finalCount: FinalCountItem[] = [];
this.finalCount.push({[this.animal]: this.count});