What is the easiest way to get value from `Map<...
# announcements
d
What is the easiest way to get value from
Map<String,String>
with case insensitive
String
key? More context and detailed scenario in the thread...
I might have a
Map<String,String>
like this
Copy code
val input = mutableMapOf<String, String>().apply {
    put("@Username", "John Doe")
    // OR
    // put("@USERNAME", "John Doe")
    // OR
    // put("@username", "John Doe")
}
And I have to use
username
at lots of different places so I have created a getter extension on
Map<String,String>
like this
Copy code
interval val Map<String, String>.username: String?
    get() {
        val caseInsensitiveMap = TreeMap<String, String>(String.CASE_INSENSITIVE_ORDER)
        caseInsensitiveMap.putAll(this)
        return caseInsensitiveMap["@USERNAME"]
    }
I know this is not a very optimized way, that's why the question 😬 And I will access it like this
Copy code
val username = input.username
println(username) // Must print "John Doe"
a
Perhaps wrap keys into a class with custom equals/hashCode implementations?
☝️ 1
d
Actually I can't change definition of
Map
because it's already in use at many place in the project, so I can't change the key now
s
But you can change the definition of what you put as keys in these `Map`s? Then @Arkadii Ivanov's is the way to go
If it has to be a Map<*String*, String>, then Arkadii's suggestion won't work, since Strings are not extensible (you can't sub-class them)
a
For JVM you can try TreeMap which accepts a Comparator. But it will give O(logN) time.
n
can you call
lowercase()
on the key on insert ? that would not chang the type.. but it would avoid duplicates
d
I don't do insertion, my project is a library used by other developers (that's why I'm worried about the casing). I guess the best thing I think of is to change definition of
Map
to
TreeMap
v
Copy code
val Map<String, String>.username: String?
    get() = this.asSequence()
        .filter { it.key.uppercase() == "@USERNAME" }
        .firstOrNull()?.value
@Danish Ansari maybe like this...
in fact, your version will get the last matching value. To do this, use lastOrNull instead of firstOrNull, which is somewhat slower...
d
Thanks a lot @Vadim Kapustin I'll surely try this approach