Kotlin - replace item in a map

Viewed 1158

I'm write a function that should replace an item in map. I have reach it using HashMap but is possible to write something similar in a "kotlinmatic way"?

fun HashMap<Int, String>.ignoreFields(path: String, fieldsToIgnore: FieldsToIgnore) = {
    val filtered: List<Field> = fieldsToIgnore.ignoreBodyFields.filter { it.tagFile == path }

    filtered.forEach {
        val updatedJson = JsonPath.parse(JsonPath.parse(this[it.order])
                .read<String>(whatevervariable))
                .delete(it.field)
                .apply { set("equalJson", this) }
                .jsonString()

        this.replace(it.order, updatedJson)
    }

    return this
}

update using map based on answers:

fun Map<Int, String>.ignoreFields(path: String, fieldsToIgnore: FieldsToIgnore): Map<Int, String> {
    val filtered = fieldsToIgnore.ignoreBodyFields.filter { it.tagFile == path }

    return this.mapValues {m ->
        val field = filtered.find { it.order == m.key }

        if (field != null) {
            JsonPath.parse(JsonPath.parse(this[field.order])
                    .read<String>(whatevervariable))
                    .delete(field.field)
                    .apply { set(pathBodyEqualToJson, this) }
                    .jsonString()
        } else {
            m.value
        }
    }
}
2 Answers

You can use mapValues to conditionally use different value for same key. This will return a new immutable map

Update: filtered will now be a map of order to updatedJson

fun HashMap<Int, String>.ignoreFields(path: String,
                                      fieldsToIgnore: FieldsToIgnore): Map<Int, String> {
    val filtered: Map<Int, String> = fieldsToIgnore.ignoreBodyFields
            .filter { it.tagFile == path }
            .map {
                val updatedJson = JsonPath.parse(JsonPath.parse(this[it.order])
                        .read<String>(whatevervariable))
                        .delete(it.field)
                        .apply { set("equalJson", this) }
                        .jsonString()
                it.order to updatedJson
            }
    return this.mapValues {
        filtered.getOrElse(it.key) { it.value }
    }
}

A possible solution is to use mapValues() operator, e.g.:

fun Map<Int, String>.ignoreFields(ignoredFields: List<Int>): Map<Int, String> {
    return this.mapValues { 
        if (ignoredFields.contains(it.key)) {
            "whatever"
        } else {
            it.value
        }
    }
}

// Example
val ignoredFields = listOf<Int>(1,3)
val input = mapOf<Int, String>(1 to "a", 2 to "b", 3 to "c")
val output = input.ignoreFields(ignoredFields)
print(output)
// prints {1=whatever, 2=b, 3=whatever}
Related