根据条件在 Kotlin 中创建列表
Creating a List in Kotlin based on Conditions
此刻我的乐趣是:
private fun validateArguments(city: String, state: String, country: String, zip: String): List<String> {
val list: MutableList<String> = mutableListOf()
if (city.isNullOrBlank()) list.add("Invalid city")
if (state.isNullOrBlank()) list.add("Invalid state")
if (country.isNullOrBlank()) list.add("Invalid country")
if (zip.isNullOrBlank()) list.add("Invalid zip code")
return list.toList()
}
我想知道是否有更优雅的方法来创建列表。
我猜最后的列表也可能是一个 MutableList。
我不确定是否有明显更好的方法;已经相当简洁明了了。
但这里有一个替代方案,使用 listOfNotNull
and takeIf
函数来避免显式临时列表:
private fun validateArguments(city: String, state: String, country: String, zip: String)
= listOfNotNull(
"Invalid city".takeIf{ city.isNullOrBlank() },
"Invalid state".takeIf{ state.isNullOrBlank() },
"Invalid country".takeIf{ country.isNullOrBlank() },
"Invalid zip code".takeIf{ zip.isNullOrBlank() })
此处takeIf()
returns不满足条件则为null;然后 listOfNotNull()
删除所有这些空值,只留下满足的错误。
如果您使用的是 Kotlin 1.6+,则有用于列表、集合和映射的构建器 API:
val list = buildList {
if (city.isNullOrBlank()) add("Invalid city")
if (state.isNullOrBlank()) add("Invalid state")
if (country.isNullOrBlank()) add("Invalid country")
if (zip.isNullOrBlank()) add("Invalid zip code")
}
这允许将可变句柄的范围限制在列表中,并且只公开只读接口。它也非常适合提取的方法。
如果没有一些疯狂的解决方案(例如反射),你不能做太多的事情来缩短它。如果所有参数总是字符串并且错误消息总是非常相似,您可以删除一些冗余代码:
@OptIn(ExperimentalStdlibApi::class)
private fun validateArguments2(city: String, state: String, country: String, zip: String) = buildList {
for ((value, name) in listOf(
city to "city",
state to "state",
country to "country",
zip to "zip code"
)) {
if (value.isBlank()) {
add("Invalid $name")
}
}
}
但是如果你没有大量的这些参数,它就没有太大意义。
此外,如果您的参数甚至不可为空,则您无需检查空值 (isNullOrBlank()
)。
更新
或没有实验性 API:
private fun validateArguments2(city: String, state: String, country: String, zip: String) : List<String> {
return listOf(
city to "city",
state to "state",
country to "country",
zip to "zip code"
).filter { it.first.isBlank() }
.map { "Invalid ${it.second}" }
}
但是对于 reader 来说,它会比你最初的实现更加神秘,所以你真的需要有一个这样做的理由。
此刻我的乐趣是:
private fun validateArguments(city: String, state: String, country: String, zip: String): List<String> {
val list: MutableList<String> = mutableListOf()
if (city.isNullOrBlank()) list.add("Invalid city")
if (state.isNullOrBlank()) list.add("Invalid state")
if (country.isNullOrBlank()) list.add("Invalid country")
if (zip.isNullOrBlank()) list.add("Invalid zip code")
return list.toList()
}
我想知道是否有更优雅的方法来创建列表。 我猜最后的列表也可能是一个 MutableList。
我不确定是否有明显更好的方法;已经相当简洁明了了。
但这里有一个替代方案,使用 listOfNotNull
and takeIf
函数来避免显式临时列表:
private fun validateArguments(city: String, state: String, country: String, zip: String)
= listOfNotNull(
"Invalid city".takeIf{ city.isNullOrBlank() },
"Invalid state".takeIf{ state.isNullOrBlank() },
"Invalid country".takeIf{ country.isNullOrBlank() },
"Invalid zip code".takeIf{ zip.isNullOrBlank() })
此处takeIf()
returns不满足条件则为null;然后 listOfNotNull()
删除所有这些空值,只留下满足的错误。
如果您使用的是 Kotlin 1.6+,则有用于列表、集合和映射的构建器 API:
val list = buildList {
if (city.isNullOrBlank()) add("Invalid city")
if (state.isNullOrBlank()) add("Invalid state")
if (country.isNullOrBlank()) add("Invalid country")
if (zip.isNullOrBlank()) add("Invalid zip code")
}
这允许将可变句柄的范围限制在列表中,并且只公开只读接口。它也非常适合提取的方法。
如果没有一些疯狂的解决方案(例如反射),你不能做太多的事情来缩短它。如果所有参数总是字符串并且错误消息总是非常相似,您可以删除一些冗余代码:
@OptIn(ExperimentalStdlibApi::class)
private fun validateArguments2(city: String, state: String, country: String, zip: String) = buildList {
for ((value, name) in listOf(
city to "city",
state to "state",
country to "country",
zip to "zip code"
)) {
if (value.isBlank()) {
add("Invalid $name")
}
}
}
但是如果你没有大量的这些参数,它就没有太大意义。
此外,如果您的参数甚至不可为空,则您无需检查空值 (isNullOrBlank()
)。
更新
或没有实验性 API:
private fun validateArguments2(city: String, state: String, country: String, zip: String) : List<String> {
return listOf(
city to "city",
state to "state",
country to "country",
zip to "zip code"
).filter { it.first.isBlank() }
.map { "Invalid ${it.second}" }
}
但是对于 reader 来说,它会比你最初的实现更加神秘,所以你真的需要有一个这样做的理由。