diff --git a/dsl/src/commonMain/kotlin/it/unibo/collektive/field/operations/Fields.kt b/dsl/src/commonMain/kotlin/it/unibo/collektive/field/operations/Fields.kt index 57d4a36fa..24258fcd1 100644 --- a/dsl/src/commonMain/kotlin/it/unibo/collektive/field/operations/Fields.kt +++ b/dsl/src/commonMain/kotlin/it/unibo/collektive/field/operations/Fields.kt @@ -91,3 +91,19 @@ inline fun Field.none(crossinline predicate: (T) -> Boolean */ inline fun Field.noneWithSelf(crossinline predicate: (T) -> Boolean): Boolean = !anyWithSelf(predicate) + +/** + * Returns a new field containing [replaceWith] for each element that satisfies the [predicate]. + */ +inline fun Field.replaceMatchingWithId( + replaceWith: T, + crossinline predicate: (ID, T) -> Boolean, +): Field = mapWithId { id, value -> if (predicate(id, value)) replaceWith else value } + +/** + * Returns a new field containing [replaceWith] for each element that satisfies the [predicate]. + */ +inline fun Field.replaceMatching( + replaceWith: T, + crossinline predicate: (T) -> Boolean, +): Field = replaceMatchingWithId(replaceWith) { _, value -> predicate(value) } diff --git a/dsl/src/commonTest/kotlin/it/unibo/collektive/field/FieldOpsTest.kt b/dsl/src/commonTest/kotlin/it/unibo/collektive/field/FieldOpsTest.kt index 62cb903f9..1d8c4a249 100644 --- a/dsl/src/commonTest/kotlin/it/unibo/collektive/field/FieldOpsTest.kt +++ b/dsl/src/commonTest/kotlin/it/unibo/collektive/field/FieldOpsTest.kt @@ -8,6 +8,7 @@ import it.unibo.collektive.field.Field.Companion.fold import it.unibo.collektive.field.Field.Companion.foldWithId import it.unibo.collektive.field.Field.Companion.hood import it.unibo.collektive.field.Field.Companion.hoodWithId +import it.unibo.collektive.field.operations.replaceMatching class FieldOpsTest : StringSpec({ val emptyField = Field(0, "localVal") @@ -71,4 +72,13 @@ class FieldOpsTest : StringSpec({ field.asSequence().toList() shouldContainAll sequenceOf(0 to 0, 1 to 10, 2 to 20).toList() } + "The replaceMatching on an empty field should return an empty field" { + emptyField.replaceMatching("replaced") { it == "no-data" } shouldBe emptyField + } + "The replaceMatching should return the same field if the predicate is not satisfied" { + field.replaceMatching(Int.MAX_VALUE) { it == 42 } shouldBe field + } + "The replaceMatching should return a field with the replaced values" { + field.replaceMatching(42) { it == 10 } shouldBe Field(0, 0, mapOf(1 to 42, 2 to 20)) + } })