I have a List<List> and need to form a mutable list of lists out of it.
fun trial (check: List<List<Int>>): Int {
val mutableCheck : MutableList<MutableList<Int>> = //mutableListOf(check)?
}
I tried various ways, but not able to make it work.
val mutableCheck = check.map { it.toMutableList() }.toMutableList()
Related
I am trying to verify that .shuffled() on a list is called, but get an error on running because of a prior .take(6) call on the list, and I cannot see a way around this.
Here is some code that gets the same error:
val mockList =
mockk<List<String>> { every { shuffled() } returns mockk(relaxed = true) }
val choiceList = spyk(listOf("String1", "String2")) { every { take(6) } returns mockList }
val tmp = choiceList.take(6)
val tmp2 = tmp.shuffled()
verify {mockList.shuffled())
On line 4, I get the following error:
class io.mockk.renamed.java.util.List$Subclass0 cannot be cast to class java.lang.Integer (io.mockk.renamed.java.util.List$Subclass0 is in unnamed module of loader 'app'; java.lang.Integer is in module java.base of loader 'bootstrap')
Attempting to go around by directly verifying on choiceList.take(6).shuffled() and combining the two tmp vals into one has had no success, as it gets true whether or not .shuffled() gets called. Also, switching from a spy to a mock for choiceList has also not worked.
Edit: Note, since this is a toy example, the take() is completely necessary, and cannot be removed, as it has real use in the actual code.
Interesting one!
I think in current implementation it is not possible. The easy answer would be "this test misses the declaration of wrapping static class" (as extension methods are just the same as java static methods for JVM). But if we add it...
#Test
fun test() {
mockkStatic("kotlin.reflect.jvm.internal.impl.utils.CollectionsKt")
val iterClass = mockkClass(Iterable::class)
val mockList = mockk<List<String>> { every { shuffled() } returns mockk(relaxed = true) }
with(iterClass) {
every { take(6) } returns mockList
val tmp = take(6)
val tmp2 = tmp.shuffled()
verify {
mockList.shuffled()
}
}
}
we have a Recursion detected in a lazy value under LockBasedStorageManager#1d2ad266 (DeserializationComponentsForJava.ModuleData) which is understandable - we just mocked the whole extensions package. And it is not possible to mock only one extension method leaving others intact. (source: https://github.com/mockk/mockk#extension-functions)
However, I'd do the following. Why not make our own extension functions which call the original and mock those?
It would go like this:
Main.kt:
package root
...
fun <T> Iterable<T>.take(n: Int): Iterable<T> {
val m = Iterable<T>::take
return m.call(this)
}
fun <T> Iterable<T>.shuffled(): Iterable<T> {
val m = Iterable<T>::shuffled
return m.call(this)
}
Test.kt:
package root
...
#Test
fun test() {
// note this changed
mockkStatic("root.MainKt")
val iterClass = mockkClass(Iterable::class)
val mockList = mockk<List<String>> { every { shuffled() } returns mockk(relaxed = true) }
with(iterClass) {
every { take(6) } returns mockList
val tmp = take(6)
val tmp2 = tmp.shuffled()
verify {
mockList.shuffled()
}
}
}
The only downside here I think is that it's reflection (duh!) So, this can possibly affect performance and has the requirement to have implementation(kotlin("reflect")) in the dependencies (to use call()). If it is not feasible I think there's no clean solution.
val mockList: List<String> = mockk(relaxed = true)
mockList.shuffled()
verify { mockList.shuffled() }
This works for me. The problem is that take of choiceList cannot be mocked somehow. Is that really necessary?
I try to make a variable sized immutable list in Kotlin, but the only way I found is this. Isn't there a more clean way to do it ?
val size = nextInt(0, 50)
val list = mutableListOf<Post>()
for (i in 0..size) {
list.add(getRandomPost())
}
val immutableList = Collections.unmodifiableList(list)
When my source is another list (with random size) I can do val immutableList = otherList.map{ /* thing that will be add() */ } but found nothing similar for just integrer
U can benefit on kotlin collections extensions and use List builder
val list: List<Post> = List(Random.nextInt(0, 50)) {
getRandomPost()
}
I'm trying to add an element list to the list of string, but I found Kotlin does not have an add function like java so please help me out how to add the items to the list.
class RetrofitKotlin : AppCompatActivity() {
var listofVechile:List<Message>?=null
var listofVechileName:List<String>?=null
var listview:ListView?=null
var progressBar:ProgressBar?=null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_retrofit_kotlin)
listview=findViewById<ListView>(R.id.mlist)
var apiInterfacee=ApiClass.client.create(ApiInterfacee::class.java)
val call=apiInterfacee.getTaxiType()
call.enqueue(object : Callback<TaxiTypeResponse> {
override fun onResponse(call: Call<TaxiTypeResponse>, response: Response<TaxiTypeResponse>) {
listofVechile=response.body()?.message!!
println("Sixze is here listofVechile ${listofVechile!!.size}")
if (listofVechile!=null) {
for (i in 0..listofVechile!!.size-1) {
//how to add the name only listofVechileName list
}
}
//println("Sixze is here ${listofVechileName!!.size}")
val arrayadapter=ArrayAdapter<String>(this#RetrofitKotlin,android.R.layout.simple_expandable_list_item_1,listofVechileName)
listview!!.adapter=arrayadapter
}
override fun onFailure(call: Call<TaxiTypeResponse>, t: Throwable) {
}
})
}
}
A more idiomatic approach would be to use MutableList instead of specifically ArrayList. You can declare:
val listOfVehicleNames: MutableList<String> = mutableListOf()
And add to it that way. Alternatively, you may wish to prefer immutability, and declare it as:
var listOfVehicleNames: List<String> = emptyList()
And in your completion block, simply reassign it:
listOfVehicleNames = response.body()?.message()?.orEmpty()
.map { it.name() /* assumes name() function exists */ }
Talking about an idiomatic approach... 🙄
When you can get away with only using immutable lists (which means usually in Kotlin), simply use + or plus. It returns a new list
with all elements of the original list plus the newly added one:
val original = listOf("orange", "apple")
val modified = original + "lemon" // [orange, apple, lemon]
original.plus("lemon") yields the same result as original + "lemon". Slightly more verbose but might come in handy when combining several collection operations:
return getFruit()
.plus("lemon")
.distinct()
Besides adding a single element, you can use plus to concatenate a whole collection too:
val original = listOf("orange", "apple")
val other = listOf("banana", "strawberry")
val newList = original + other // [orange, apple, banana, strawberry]
Disclaimer: this doesn't directly answer OP's question, but I feel that in a question titled "How to add an item to a list in Kotlin?", which is a top Google hit for this topic, plus must be mentioned.
If you don't want or can't use array list directly use this code for add item
itemsList.toMutableList().add(item)
itemlist : list of your items
item : item you want to add
instead of using a regular list which is immutable just use an arrayListof which is mutable
so your regular list will become
var listofVehicleNames = arrayListOf("list items here")
then you can use the add function
listOfVehicleNames.add("what you want to add")
you should use a MutableList like ArrayList
var listofVechileName:List<String>?=null
becomes
var listofVechileName:ArrayList<String>?=null
and with that you can use the method add
https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-mutable-list/add.html
For any specific class, the following may help
var newSearchData = List<FIRListValuesFromServer>()
for (i in 0 until this.singleton.firListFromServer.size) {
if (searchText.equals(this.singleton.firListFromServer.get(i).FIR_SRNO)) {
newSearchData.toMutableList().add(this.singleton.firListFromServer.get(i))
}
}
val listofVechile = mutableListOf<String>()
Declare mutable list like that and you will be able to add elements to list :
listofVechile.add("car")
https://kotlinlang.org/docs/collections-overview.html
I see many posts about converting the table(s) in a DataSet to a list of DataRows or other row data but I was unable to find anything about this question. This is what I came up with using .Net 3.0:
public static List<DataTable> DataSetToList(DataSet ds)
{
List<DataTable> result = new List<DataTable>();
foreach (DataTable dtbl in ds.Tables)
{
result.Add(dtbl);
}
return result;
}
Is there a better way, excluding an extension method?
Thanks
Based on Why LINQ casting with a Data.DataTableCollection this will work;
List<DataTable> result = new List<DataTable>(ds.Tables.Cast<DataTable>())
IEnumerable<DataTable> sequence = dt.AsEnumerable();
or
List<DataTable> list = dt.AsEnumerable().ToList();
I have found successes using ideas of immutable List but I am stumped when come to this piece of code here. I find myself has written something more Java than of Scala style. I would prefer to use List(...) instead of Buffer(...) but I don't see how I can pass the same modified immutable List to the next function. guesses is also modified within eliminate(...).
Any suggestions to help me to make this the Scala way of doing this is appreciated. Thanks
val randomGuesses = List(...) // some long list of random integers
val guesses = randomGuesses.zipWithIndex.toBuffer
for ( s <- loop()) {
val results = alphaSearch(guesses)
if (results.size == 1) {
guesses(resultes.head._2) = results.head._1
eliminate(guesses, resultes.head._2)
}
else {
val results = betaSearch(guesses)
if (results.size == 1) {
guesses(resultes.head._2) = results.head._1
eliminate(guesses, resultes.head._2)
} else {
val results = betaSearch(guesses)
if (results.size == 1) {
guesses(resultes.head._2) = results.head._1
eliminate(guesses, resultes.head._2)
}
}
}
}
Here are some general tips since this might be better suited for codereview and the code posted is incomplete with no samples.
You can use pattern matching instead of if and else for checking the size.
results.size match{
case 1 => ... //Code in the if block
case _ => ... //Code in the else block
}
Instead of mutating guesses create a new List.
val newGuesses = ...
Then pass newGuesses into eliminate.
Lastly, it looks like eliminate modifies guesses. Change this to return a new list. e.g.
def eliminate(list: List[Int]) = {
//Eliminate something from list and return a new `List`
}