Reputation: 81
I have a chain of predicate clauses, something like this
student?.firstName?.equals("John") ?: false &&
student?.lastName?.equals("Smith") ?: false &&
student?.age?.equals(20) ?: false &&
student?.homeAddress?.equals("45 Boot Terrace") ?: false &&
student?.cellPhone?.startsWith("123456") ?: false
I have found that instead of && it's possible to switch to Boolean predicate and(), but overall it doesn't make code more concise.
Is there is a way in Kotlin to simplify such expression?
Upvotes: 4
Views: 2696
Reputation: 2469
Not exactly what OP wants, but it seems like the issue here is comparing between two objects of type Student
rather than chaining predicates.
Not sure what the use case is but here's a more object-oriented solution, where we park the predicates under Student::isSimilarToJohn
(because I'm assuming this John Smith is pretty special):
data class Student(
val firstName: String?,
val lastName: String?,
val age: Int?,
val homeAddress: String?,
val cellPhone: String?,
) {
fun isSimilarToJohn(): Boolean {
return firstName == "John" &&
lastName == "Smith" &&
age == 20 &&
homeAddress == "45 Boot Terrace" &&
cellPhone.orEmpty().startsWith("123456")
}
}
Example:
val students = listOf(
Student("John", "Smith", 20, "45 Boot Terrace", "1234568"),
Student("John", "Smith", 20, "45 Boot Terrace", "1234567"),
Student("Mary", "Smith", 20, "45 Boot Terrace", "1234567"),
Student("John", "Doe", 20, "45 Boot Terrace", "1234567"),
)
students.map { it.isSimilarToJohn() }
// [true, true, false, false]
Upvotes: 0
Reputation: 81
Thanks everyone who participated! Here is a final version of the code with notes:
student?.run {
firstName == "John" &&
lastName == "Smith" &&
age == 20 &&
homeAddress == "45 Boot Terrace" &&
cellPhone.orEmpty().startsWith("123456")
} ?: false
run {}
is called on an object student
equals
is replaced by ==
to compare boolean as well as null
values?: false
. Another option is to use == true
, but it's your personal preferenceUpvotes: 4
Reputation: 385
For example
val result = listOf(
student.firstName == "John",
student.lastName == "Smith",
student.age == 20,
student.cellPhone.orEmpty().startsWith("123456")
).all { it }
or
fun isAllTrue(first: Boolean, vararg other: Boolean): Boolean {
return first && other.all { it }
}
val result = isAllTrue(
student.firstName == "John",
student.lastName == "Smith",
student.age == 20,
student.cellPhone.orEmpty().startsWith("123456")
)
or
fun Iterable<Boolean>.isAllTrue(): Boolean {
return all { it }
}
val result = listOf(
student.firstName == "John",
student.lastName == "Smith",
student.age == 20,
student.cellPhone.orEmpty().startsWith("123456")
).isAllTrue()
Upvotes: 0