2

Trying to get a value from a map only using the beginning of a key. If a have map of <strings,strings> and I know the beginning of the key will be either "aaa", "bbb", or "ccc", is there a way to retrieve that String Value.

Example Map

"aaa_unknownText" -> "hello world"

"bbb_unknown_Text" -> "hello mars"

"ccc_unknown_TEXT" -> "hello jupiter"

Want to get the String Value of "bbb" which is "hello mars"

My thought process was to get the Keys in a list. Then go through list checking each string until I found a match, saving that Key in val foundKey. Then using map.get(foundKey) to get the String Value. New to Kotlin wanted to know if there was a different way, maybe using map.filter option, Thanks!

-Thanks for your response! Took pieces of code and currently have

map.filterkeys { it.startsWith("bbb") }.toList().map{ it.second }[0]

The keys "aaa", "bbb", and "ccc" will only appear once in the map, and guaranteed will appear. Needed the result value as a string so turned it into a list and got index [0]

1
  • If it is guaranteed to have each prefix only once, then depending on what's the source of this map, you could consider not storing the whole key in the first place. When you add anything to it, store it under "aaa" key already. Commented Jul 31, 2023 at 6:41

1 Answer 1

2

If you are certain that there will only be at most one entry whose key starts with your given string, you can use firstNotNullOfOrNull:

map.firstNotNullOfOrNull { e -> e.value.takeIf { e.key.startsWith("aaa") } }

This will return null if no key matches.

firstNotNullOfOrNull returns the first value in that map for which the closure returns a non-null value, or null if the closure returns null for all the entries. The closure I passed here uses takeIf. It returns the entry's value if the entry's key starts with "aaa", or null otherwise.

If you have could have more than one matching key, use filterKeys to get a map with all the non-matching keys removed, then get their values.

map.filterKeys { it.startsWith("aaa") }.values

This will give you a Collection<String> with all the values corresponding to matching keys.

Note that both of these approaches are O(n) time. Maps aren't really supposed to be used like this. If there are no more than one matching key, and you need to access the map multiple times, I would suggest making a new map with only the beginning portion of the keys.

// assuming you want to match the part before the first underscore
val newMap = map.mapKeys { it.key.split("_").first() }

Then you can query newMap instead.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.