Koitt
Koitt

Reputation: 1074

Kotlin - Check if one map contains all entries from another

I'm trying to create a function in kotlin that takes two maps and returns true if one is contained in another, that is, if all the entries in map A are in map B (but B can have other entries)

The code I have is

private fun matchesMap(map1: Map<String, Any>, reference: Map<String, Any>): Boolean {
    return reference.all { k, v ->  map1.get(k).equals(v) }
}

But this gives a Type mismatch: inferred type is (Map.Entry<String, Any>, ???) -> Boolean but (Map.Entry<String, Any>) -> Boolean was expected and I'm not sure what's wrong. I've tried to replace it with map1[k] == v but I still get the same error. How can I fix the compilation error?

Upvotes: 1

Views: 3461

Answers (2)

user2340612
user2340612

Reputation: 10713

The reason why it doesn't compile is that you forgot a pair of parenthesis around k, v. This makes a big difference because with the parenthesis you're creating a lambda expecting 1 argument, which is destructured into 2 variables (k and v), while without parenthesis you're providing a lambda that expects 2 different arguments. The latter is incompatible with the signature of all, as correctly pointed out by @Gennady.

Also, another problem is caused by the .equals method, because get is returning a nullable value (what if there's no such key in the map?), so the equals method should be invoked as ?.equals, which can be simplified to ==. Also, get can be simplified too to [].

Putting all together:

private fun matchesMap(map1: Map<String, Any>, reference: Map<String, Any>): Boolean {
    return reference.all { (k, v) ->  map1[k] == v }
}

Upvotes: 7

Gennady
Gennady

Reputation: 372

According to specification all method - argument of lambda is Entry. You cannot get key and value directly, so change it to Entry.

Correct code:

reference.all { entry ->  map1.get(entry.key) == entry.value }

You should use Map method equals. It does the same.

Upvotes: 4

Related Questions