¿Cómo se usa `filter` en la instancia de Map en Kotlin?

Veo que #filter está definido en Map , pero no puedo descifrar cómo usarlo. ¿Alguien quiere compartir un ejemplo?

Tengo una instancia TreeMap profundamente anidada ( TreeMap<String, Map<String, Map<*, *>>> ) y quiero filter/find la primera (que es la única en el dominio) key de nivel superior que tiene una ciertas características asociadas con algo más profundo en el valor.

Así es como se ve la información:

 { "i1": { "aliases": {} }, "i2": { "aliases": {} }, "i3": { "aliases": {} }, "i4": { "aliases": { "alias-im-looking-for": {} } } } 

Tengo este siguiente código no funcional que lo resuelve ahora mismo:

 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 

Parece que lo que necesita es la parte key de la primera input que coincida con sus criterios. Algo como esto (una sola línea intencional) debería ayudar:

 val currentIndexName = indexToAliasMappings.filterValues { it["aliases"]?.containsKey(alias) ?: false }.keys.firstOrNull() ?: "" 

La lambda de .filter devuelve un valor boolean para cada input en el map. Si ese valor boolean se evalúa como true , esa input es parte de la colección devuelta. Si ese valor boolean se evalúa como false , esa input se filtra.

 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 

No puede invocar firstOrNull en el map en sí, pero puede invocarlo en su set de entries :

  val currentIndexName = indexToAliasMappings.entries.firstOrNull { it.value["aliases"]?.containsKey(alias) == true }?.key 

firstOrNull itera a través de inputs de map y se detiene en una primera input que coincida con el pnetworkingicado. filterValues se requieren asignaciones intermedias de maps como en la variante con filter o filterValues filter .

  • ¿Cómo colocar una extensión de Kotlin en un file de class?
  • Inicialización lenta del miembro anulable
  • Android onCheckedChangeListener comportamiento bizzare
  • ¿Por qué no puedo usar lambda para la interfaz en kotlin?
  • Kotlin: ¿cómo decidir entre "lateinit" y "variable anulable"?
  • ¿Es seguro llamar a kclass.memberProperties en un object desconocido (Cualquiera)?
  • La inferencia de tipo del comstackdor Kotlin no puede elegir qué método llamar (ambigüedad con types generics)
  • Reactive Spring 5 Nombre principal de security en Kotlin
  • Consumidor actuando de manera extraña en kotlin
  • Problema con el método de extensión en el script de Kotlin
  • Agregar vista personalizada a includedView