I have an array of userIDs, which contains specific users from a certain group.
{userID1,userID2}
val userIDArrayList: ArrayList<String> = ArrayList()
userIDArrayList.add(userID1)
userIDArrayList.add(userID2)
I want to make a master array which contains several different user arrays.
[{userID1, userID2}, {userID3, userID4}]
How can I do that in kotlin?
mutableListOf(mutableListOf("yourobject"),mutableListOf("yourobject"))
or
val myList = mutableListOf<MutableList<yourobject>>()
First, declare the master array which will contains other arrays
val masterList = mutableListOf<List<String>>()
Secondly, declare the arrays which will be nested. Assuming userID1, userID2, userID3, userID4 are declared somewhere
val subList1 = listOf(userID1,userID2)
val subList2 = listOf(userID3,userID4)
Finally, add the sublists to the master
masterList.add(subList1)
masterList.add(subList2)
Of course you can do all of this with only one line during masterList instantiation
val masterList = mutableListOf<List<String>>(
listOf(userID1,userID2),
listOf(userID3,userID4)
)
Related
My output looks like this :
["Floor 0","Floor 1","Floor 2"]
It comes as a string. But I want to fetch each element of this array. How can I do this using Kotlin ?
implement this library Gson
you can use it like this
val text = "[\"Floor 0\",\"Floor 1\",\"Floor 2\"]"
val array = Gson().fromJson(text, ArrayList::class.java)
array.forEach {
Log.e(TAG, "onCreate: it $it")
}
Just use regular expressions to create a match for each CharSequence between the double quotes. As you want to use only the values between the quotes, you can extract the first index group values. The following code snippet does what you are asking for in Kotlin:
val str = "[\"Floor 0\",\"Floor 1\",\"Floor 2\"]"
val pattern = Regex( "\"(.*?)\"")
val fetched_elements = pattern.findAll(str).map {
it.groupValues[1]
}.toList()
// creates the list: [Floor 0, Floor 1, Floor 2]
Use also this RegExr example to explore this in detail with explanation.
If your internal strings aren't allowed to have commas, you could do it with a split function to convert it into a list:
var lst = str.replace("\"", "").split(",")
If your internal strings can have trailing whitespace, this would be better:
var lst = str.replace("\"", "").split(",").map { it.trim() }
In the above code lines, the replace function removes the quotes surrounding each internal string; the split separates the string at each comma; and the trim function removes any surrounding whitespace characters.
If your internal strings can contain commas, you're better off learning about and using regular expressions as mentioned in another answer.
I copyed List type variable to new one of MutableList type,
then updated value of new one's item.
But origin variable was updated too.
Are these point to same address?
Why?
var foodList = listOf(
FoodModel("curry", 2000)
FoodModel("rice", 1000)
)
// copyed foodList to new variable MutableList<FoodModel> type
val tempList = foodList as MutableList<FoodModel>
Log.e("weird", tempList[position].name+" "+tempList[position].price)
Log.e("weird", foodList[position].name+" "+foodList[position].price)
//E/weird: rice 1000
//E/weird: rice 1000
tempList[position] = FoodModel(nameEdit.text.toString(), priceEdit.text.toString().toInt())
Log.e("weird", tempList[position].name+" "+tempList[position].price)
Log.e("weird", foodList[position].name+" "+foodList[position].price)
//E/weird: rice 3333
//E/weird: rice 3333
Are these point to same address?
Yes, because foodList as MutableList<FoodModel> is not copying, it is type casting and it can lead to a ClassCastException or UnsupportedOperationException. To copy a list use toMutableList()
val tempList = foodList.toMutableList()
FoodModel is reference type, so your foodList is a list of references. When you copy it, you get a new list with old references to models, so when you modify value of reference in new list it is reflected to the previous list.
You can solve this by creating a deep copy of the list. For example:
data class FoodModel(val str: String, val int: Int)
foodList.mapTo(mutableListOf(), FoodModel::copy)
how can i change item's data type in arrays or lists in kotlin ?
i found a usual way but i need an easier and faster and better way to change data type of an array :)
fun typeChanger (data:MutableList<Number>): DoubleArray {
val result = mutableListOf<Double>()
for (i in data.iterator()){
result.add(i.toDouble())
}
return result.toDoubleArray()
}
val x = mutableListOf<Number>(+1,+1,-1,-1)
val xx:DoubleArray = typeChanger(x) // It works but i need an easier and faster and better way :)
Array map is your friend. You could keep your function and simplify, or remove it completely as below:-
val xx = x.map { it.toDouble() }
Once it's a list of doubles, you can then leave as a list or use .toDoubleArray() if you need an array.
Trying to understand the difference between map and mapTo in kotlin. Could anyone help me out in explaining the difference using some examples
map creates a new list internally, and puts its results into that list, then it returns that list:
val mapResult = listOf(1, 2, 3).map { it * 2 } // you get a new list instance returned
If you use mapTo instead, you can specify the destination where it places the mapped elements, by providing your own list as the first parameter:
val myList = ArrayList<Int>()
val mapToResult = listOf(1, 2, 3).mapTo(myList) { it * 2 }
If the list you're provided already has elements in it, those will be kept, and the new ones will be added to those. It also returns the destination list for convenience.
map: map can transform your data(List) and can return either complete modified list or List of a variable of model, for ex:
You have a model:
data class Student(var id:String, var name:String, var className:String)
Now from arrayOfStudent, we want all the name of students in capital letters, so apply map like this:
val listOfNamesInCapitalLetters= arrStudent.map {
it.name= it.name.toUpperCase()
}
Log.d("map_test", "student's name: $listOfNamesInCapitalLetters")
The output will be:
[AMIT, VIJAY, SUMIT, KARAN, SMAEER]
Now, what if you want the whole student list, with name in capital letters and className is increased by 1, let's do this:
val result= arrStudent.map {
it.name= it.name.toUpperCase() // transforming name to upper case
it.className=it.className+1 // increasing class by 1
it // <- Note that we return it, because list will be prepared of the object which is returned by last statement of map
}
Log.d("modified_list", result.toString())
The output will be:
[Student(id=1, name=AMIT, className=6), Student(id=2, name=VIJAY, className=7), Student(id=3, name=KARAN, className=8), Student(id=4, name=VIRAT, className=9), Student(id=5, name=SAM, className=10)]
mapTo: If you want to transform your list into a different type of list then use mapTo, for example, we have a different data class named: CompactStudent
data class CompactStudent(val id:String, val name:String)
Now if we want to convert List to List, note that CompactStudent contains id and name but not the className as compared to Student model, so to do this:
val arrayList=ArrayList<CompactStudent>()
arrStudent.mapTo(arrayList){
CompactStudent(it.id,it.name)
}
Log.d("studentCompact", arrayList.toString())
Output will be:
[StudentCompct(id=1, name=AMIT), StudentCompct(id=2, name=VIJAY), StudentCompct(id=3, name=KARAN), StudentCompct(id=4, name=VIRAT), StudentCompct(id=5, name=SAM)]
Begin new project in Kotlin and missing those.
Try to get string-array recources but can't.
In strings.xml I palced next items.
<string-array name="themeList">
<item>white</item>
<item>sepia</item>
<item>black</item>
<item>pink</item>
</string-array>
In code I try next:
val res: Resources = resources
val appThemeList = arrayOf(res.getStringArray(R.array.themeList))
for (value in appThemeList) {
Log.i ("value", value.toString())
}
But in logCat i see:
I/value: [Ljava.lang.String;#40145f2
And I don'r understand, what I do incorrectly.
replace
val appThemeList = arrayOf(res.getStringArray(R.array.themeList))
to
val appThemeList = res.getStringArray(R.array.themeList)
In other case you got array
val myArray = res.getStringArray(R.array.themeList) //already array
And added to another array
arrayOf(myArray) // array of arrays
In android is depend on context when outside Activity like this
val themes = context.resources.getStringArray(R.array.themeList)
or without context is direct to resource when inside Activity
val themes = resources.getStringArray(R.array.themeList)
As we know res.getStringArray return arraylist so you do not need to write arrayOf on your code.
Simple way to achieve your goal is:-
val list = res.getStringArray(R.array.list);
We can use arrayOf when we have to define our array or we have already arraylist like below :-
val myArray = arrayOf(4, 5, 7, 3);
Try this,
val Lines = Arrays.asList(resources.getStringArray(R.array.list))
In kotlin use :
var yourVar = resources.getStringArray(R.array.your_string_array)
In kotlin, also need to use context like below
var arry = context.resources.getStringArray(R.array.your_string_array)
With this line of code you get exactly the element in the place of index.
val the_string = resources.getStringArray(R.array.YOUR_STRING_ARRAY)[index].toString()
This will be your res/values/strings.xml
<string-array name="YOUR_STRING_ARRAY">
<item>kJ</item>
<item>kWh</item>
<item>Btu</item>
<item>kcal</item>
</string-array>
As an example if the index is 1 then the return value is "kWh"
If you want use the path of resources in RecyclerView.Adapter Class you must put into function onBindViewHolder
val myItem = holder.itemView.resources.getStringArray(R.array.myItem_string_array)