How can I convet MutableMap to vararg values: Pair?

The name of the picture


How can I convet MutableMap<String, Any?> to vararg values: Pair<String, Any?>?



The following code is from "Kotlin for Android Developers", you can access it at https://github.com/antoniolg/Kotlin-for-Android-Developers



In order to insert a row data into CityForecastTable.NAME, I have to pass a vararg values by Source Code fun SQLiteDatabase.insert


CityForecastTable.NAME


vararg


fun SQLiteDatabase.insert



1: The author make a extension toVarargArray() to convert a MutableMap<String, Any?> to Pair<String, Any?>, I don't know whether there is a better way to do that. Do I need to use a extension function?


toVarargArray()


MutableMap<String, Any?>


Pair<String, Any?>



2: The author have to use the code it.value!! in Code C , I don't know if the code fun <K, V : Any> Map<K, V?>.toVarargArray(): Array<out Pair<K, V?>> = map({ Pair(it.key, it.value) }).toTypedArray() is right?


it.value!!


fun <K, V : Any> Map<K, V?>.toVarargArray(): Array<out Pair<K, V?>> = map({ Pair(it.key, it.value) }).toTypedArray()



3: I don't know whether the app will crash when I insert a row data of which a column include null value.


import org.jetbrains.anko.db.*
class ForecastDb(private val forecastDbHelper: ForecastDbHelper = ForecastDbHelper.instance,
private val dataMapper: DbDataMapper = DbDataMapper()) : ForecastDataSource {

fun saveForecast(forecast: ForecastList) = forecastDbHelper.use {

//dataMapper.convertFromDomain(forecast) will return CityForecast object
with(dataMapper.convertFromDomain(forecast)) {
insert(CityForecastTable.NAME, *map.toVarargArray())
}
}

}


class CityForecast(val map: MutableMap<String, Any?>, val dailyForecast: List<DayForecast>) {
var _id: Long by map
var city: String by map
var country: String by map

constructor(id: Long, city: String, country: String, dailyForecast: List<DayForecast>)
: this(HashMap(), dailyForecast) {
this._id = id
this.city = city
this.country = country
}
}



Code C


fun <K, V : Any> Map<K, V?>.toVarargArray(): Array<out Pair<K, V>> =
map({ Pair(it.key, it.value!!) }).toTypedArray()



Source Code


fun SQLiteDatabase.insert(tableName: String, vararg values: Pair<String, Any?>): Long {
return insert(tableName, null, values.toContentValues())
}



Looking for an answer drawing from credible and/or official sources.




2 Answers
2



You have pretty much everything there



Use the asterisk * operator also known as spread operator to spread your array to vararg inside function.


*


vararg



https://kotlinlang.org/docs/reference/functions.html#variable-number-of-arguments-varargs



Add ? to the value and you are ready to go


fun <K, V : Any> Map<K, V?>.toVarargArray() = map { it.key to it.value }.toTypedArray()

insert("", *mapOf("k" to "v").toVarargArray())





Thanks! Is the code fun <K, V : Any> Map<K, V?>.toVarargArray(): Array<out Pair<K, V?>> = map({ Pair(it.key, it.value) }).toTypedArray() right?
– HelloCW
Jul 23 at 3:09


fun <K, V : Any> Map<K, V?>.toVarargArray(): Array<out Pair<K, V?>> = map({ Pair(it.key, it.value) }).toTypedArray()





I don't know whether the app will crash when I insert a row data of which a column include null value.
– HelloCW
Jul 23 at 3:09



No, you do not really need an extension function for that. It may make sense to have something in place if you are calling the insert-method (or any other which requires arrays instead of a Map) often. However depending on what you call more often, you may rather supply an extension function for the specific method with the Map as parameter instead.


insert


Map


Map



If you do not want to have the extension function you can call the following directly (if you aleady have a map):


*map.map { it.key to it.value }.toTypedArray()



I wonder why the author allows Any? on the CityForecast-class as values but then decides to use value!!. I would rather recommend either using Any, that way no null values are allowed or otherwise falling back to a default, e.g. value?:"". Note that if you use Any, you probably need to ensure that your data in the database is not containing any null-values (column created with NOT NULL constraint).


Any?


CityForecast


value!!


Any


null


value?:""


Any


null


NOT NULL



You really should try it out. If it crashes you get familiar on how to deal with errors. I assume that it crashes (or at least throws a NullPointerException somewhere ;-)) if you use null values in the map and keep the mentioned extension function as then the value!!-call will fail. And note: you can always come back here to ask new questions, if there is an issue you can't resolve or you do not find any good sources for it.


NullPointerException


null


value!!





Thanks! For 1, could you show me some code instead of *map.toVarargArray() in insert(CityForecastTable.NAME, *map.toVarargArray()) ?
– HelloCW
yesterday


*map.toVarargArray()


insert(CityForecastTable.NAME, *map.toVarargArray())





Basically you can just call what is written in the extension function. Note that I do not know the method signature of insert, but I think the following will already suffice: insert(CityForecastTable.NAME, "k" to "v", "otherkey" to "othervalue", /*alternatively*/ Pair("k2", "v2"))
– Roland
yesterday




insert


insert(CityForecastTable.NAME, "k" to "v", "otherkey" to "othervalue", /*alternatively*/ Pair("k2", "v2"))





Ok. I know the signature if it's the one you posted, but with the mobile writing some comments it just disappears ;-) so the mentioned code in the comment suffices already.
– Roland
yesterday







Thank! I hope to convet MutableMap<String, Any?> to vararg values: Pair<String, Any?> as parameter of insert function. At present, I think that extension function fun <K, V : Any> Map<K, V?>.toVarargArray(): Array<out Pair<K, V>> = map({ Pair(it.key, it.value!!) }).toTypedArray() is not good.
– HelloCW
yesterday




MutableMap<String, Any?>


vararg values: Pair<String, Any?>


insert


fun <K, V : Any> Map<K, V?>.toVarargArray(): Array<out Pair<K, V>> = map({ Pair(it.key, it.value!!) }).toTypedArray()





Well, it's nearly ok. I don't trust the it.value!!. Why shouldn't I be allowed to insert null-values (except the database column has NOT NULL declared). If you don't want to use the extension function, but you want to use the map, then you can still write: *map.map { it.key to it.value }.toTypedArray().
– Roland
yesterday


it.value!!


null


NOT NULL


*map.map { it.key to it.value }.toTypedArray()






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

Arduino Mega cannot recieve any sketches, stk500_recv() programmer is not responding

Visual Studio Code: How to configure includePath for better IntelliSense results

C++ virtual function: Base class function is called instead of derived