Alex Zaitsev
Alex Zaitsev

Reputation: 1781

how to check if two Boolean? values are true in Kotlin

Sample code:

val todayCount = keyValue.value.filter {
        val after = it.expectedArrivalDate?.after(today)
        val before = it.expectedArrivalDate?.before(tomorrow)
        after != null && before != null && after && before
    }.size

If it.expectedArrivalDate were not nullable I would write something like that:

val todayCount = keyValue.value.filter {
    it.expectedArrivalDate.after(today) && it.expectedArrivalDate.before(tomorrow)
}.size

Is it possible to simplify my code?

Upvotes: 1

Views: 5050

Answers (5)

Dirk Bolte
Dirk Bolte

Reputation: 672

An alternative without an extension function: as all comparisons are based on the same field, you can actually map it while removing all nulls.

Here's a sample code with a dummy travel class so that you can see it compiles:

data class Travel(var expectedArrivalDate: Date? = null);

lateinit var keyValue: Map.Entry<String, List<Travel>>;
val today = Date.from(Instant.now())
val tomorrow = Date.from(Instant.now().plusSeconds(86400))

val todayCount = keyValue.value.mapNotNull(Travel::expectedArrivalDate).count {
    it.after(today) && it.before(tomorrow)
}

Gets the solution down to 125 characters and gets close to the code you had in mind.

Upvotes: 0

Gustavo Pagani
Gustavo Pagani

Reputation: 6988

You can create an extension functions to simplify that check.

Assuming that the type of expectedArrivalDate is Date, you could add after and before functions for the nullable Date type Date? that would return false if the instance is null, or call the original after/before functions if not null:

fun Date?.after(anotherDate: Date): Boolean = this?.after(anotherDate) ?: false
fun Date?.before(anotherDate: Date): Boolean = this?.before(anotherDate) ?: false

and leave your code as it is:

val todayCount = keyValue.value.filter {
    it.expectedArrivalDate.after(today) && it.expectedArrivalDate.before(tomorrow)
}.size

or you could just use the implementation directly in your code:

val todayCount = keyValue.value.filter {
    (it.expectedArrivalDate?.after(today) ?: false) && (it.expectedArrivalDate?.before(tomorrow) ?: false)
}.size

Upvotes: 2

mrossini
mrossini

Reputation: 408

Not sure if this can be considered a simplification but as another option you can:

val todayCount = keyValue.value.filter {
    it.expectedArrivalDate?.takeIf{d -> d.after(today)}?.takeIf{d -> d.before(tomorrow)}?.let{true}?:false
}.size

Upvotes: 0

gidds
gidds

Reputation: 18627

An alternative to extension functions or Elvis operators is simply == true.

In Java, where == compares references, that would be dangerous, as it would fail for any new Boolean instances.  But in Kotlin, == compares values using .equals() (after making the necessary null checks), so would handle that case perfectly well.

So your code could be:

val todayCount = keyValue.value.filter {
    it.expectedArrivalDate?.after(today) == true
    && it.expectedArrivalDate?.before(tomorrow) == true
}.size

Similarly, if you wanted null to count as true, you could use != false.

It's arguably not the most elegant solution, but it's probably the simplest!

Upvotes: 4

Ori Marko
Ori Marko

Reputation: 58892

Consider using variable re-declaration using ?:

variable re-declaration (and shadowing).

fun leftPad(value: String, length: Int? = null, char: Char? = null): String {
    val length = length ?: 4
    val char = char ?: ' '

Upvotes: 0

Related Questions