我看到Map
上定义#filter
,但我无法弄清楚如何使用它。有人愿意分享一个例子吗?
我有一个深度嵌套的TreeMap实例(TreeMap<String, Map<String, Map<*, *>>>
),我想filter/find
第一个(在域中唯一的)顶级键,它具有与更深层次相关的某些特征在价值中。
以下是数据的外观:
{
"i1": {
"aliases": {}
},
"i2": {
"aliases": {}
},
"i3": {
"aliases": {}
},
"i4": {
"aliases": {
"alias-im-looking-for": {}
}
}
}
我有以下非功能性代码,现在就解决了这个问题:
val indexToAliasMappingType = LinkedTreeMap<String, Map<String, Map<*, *>>>()
val indexToAliasMappings = Gson().fromJson(response.jsonString, indexToAliasMappingType.javaClass)
var currentIndexName = ""
for ((index, aliasMappings) in indexToAliasMappings) {
val hasCurrentAlias = aliasMappings.get("aliases")?.containsKey(alias)
if (hasCurrentAlias != null && hasCurrentAlias) {
currentIndexName = index
}
}
return currentIndexName
答案 0 :(得分:5)
看起来您需要的是第一个符合条件的条目的关键部分。这样的事情(单线故意)应该有所帮助:
val currentIndexName = indexToAliasMappings.filterValues { it["aliases"]?.containsKey(alias) ?: false }.keys.firstOrNull() ?: ""
答案 1 :(得分:3)
您无法在地图上调用firstOrNull
,但您可以在其entries
集上调用它:
val currentIndexName = indexToAliasMappings.entries.firstOrNull {
it.value["aliases"]?.containsKey(alias) == true
}?.key
firstOrNull
遍历映射条目并在与谓词匹配的第一个条目上停止。此处不需要具有filter
或filterValues
的变体中的中间地图分配。
答案 2 :(得分:1)
.filter
的lambda为地图中的每个条目返回一个布尔值。如果该布尔值计算为true
,则该条目是返回集合的一部分。如果该布尔值为false
,则该条目将被过滤掉。
val indexToAliasMapping = linkedMapOf(
"i1" to mapOf(
"aliases" to mapOf<Any, Any>()
),
"i2" to mapOf(
"aliases" to mapOf<Any, Any>()
),
"i3" to mapOf(
"aliases" to mapOf<Any, Any>()
),
"i4" to mapOf(
"aliases" to mapOf(
"aliases-im-looking-for" to "my-alias"
)
)
)
// If you only need one, you could also use .first instead of .filter, which
// will give you a Pair<String, Map<String, Map<*, *>>> instead of a List
val allWithNonEmptyAliases: Map<String, Map<String, Map<*, *>>> = indexToAliasMapping.filter {
it.value["aliases"]?.containsKey(alias) ?: false
}
// We use .toList() so you can get the first element (Map doesn't allow you to retrieve by index)
return allWithNonEmptyAliases.toList().first().first