3

so the past couple of hours, i have been trying to understand how the filter function works in kotlin and if it has any correlation with that of Java. basically, i have a code that's written in java and i would love to have it transcribed to kotlin

private List<Order> getFilteredOrders(Courier courier) {
        String[] glovoBoxKeywords = glovoBoxWords.toLowerCase().split(",");
        List<Vehicle> allowedVehicles = Arrays.asList(MOTORCYCLE, ELECTRIC_SCOOTER);

        return orders.stream()
                .filter(order -> {
                    String description = order.getDescription().toLowerCase();
                    if (!courier.getBox()) {
                        return Arrays.stream(glovoBoxKeywords).noneMatch(description::contains);
                    }

                    return true;
                })
                .filter(order -> {
                    Location pickupLocation = order.getPickup();
                    Location deliveryLocation = order.getDelivery();
                    Double distance = calculateDistance(pickupLocation, deliveryLocation);

                    if (distance > longDeliveryDistance) {
                        return allowedVehicles.contains(courier.getVehicle());
                    }

                    return true;
                })
                .collect(Collectors.toList());
    }

i tried this but i got at this, and was literally stuck :(

 private fun findFilteredOrder(courier: Courier) : List<Order> {
        val glovoBoxKeyWords = glovoBoxWords.toLowerCase().split(",")
        val allowedVehicles = listOf(Vehicle.ELECTRIC_SCOOTER, Vehicle.MOTORCYCLE)

        orderList.filter { order ->
            val description = order.getDescription().toLowerCase()
            if(!courier.getBox()) {

            }
            true
        }.filter {
            val pickupLocation = it.getPickup()
            val deliveryLocation = it.getDelivery()
            val distance = calculateDistance(deliveryLocation, pickupLocation)

            if(distance > longDeliveryDistance) {
                courier.getVehicle() in allowedVehicles
            }
            true
        }
    }

Please this is my first attempt and doing something with kotlin, so please go easy guys. thanks, also i'd be appreciative if anyone could help me with informative stuff as to how to understand these kotlin functions better. let, apply, associateBy... etc.. THANKS

2 Answers 2

2

The filter function in Kotlin Collections has the same principle as other frameworks/libraries, including Java Streams. Given a predicate (a function from the type of the collection to Boolean) it will return a new collection with the elements matching the predicate. You can find more information and examples of other functions and operators in the official documentation and here.

Your code was almost there, I translate the Java Stream operation to Kotlin List and rewrite the return statements to remove the redundant if

private fun findFilteredOrder(courier: Courier) : List<Order> {
    val glovoBoxKeyWords = glovoBoxWords.toLowerCase().split(",")
    val allowedVehicles = listOf(Vehicle.ELECTRIC_SCOOTER, Vehicle.MOTORCYCLE)

    orderList.filter { order ->
        val description = order.getDescription().toLowerCase()
        courier.getBox() || glovoBoxKeywords.none { it in description }
    }.filter { order ->
        val pickupLocation = order.getPickup()
        val deliveryLocation = order.getDelivery()
        val distance = calculateDistance(deliveryLocation, pickupLocation)

        distance <= longDeliveryDistance || courier.getVehicle() in allowedVehicles
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks Omar for the response and the links.
0

I don't know why no one mentioned the use of labels: https://kotlinlang.org/docs/returns.html#break-and-continue-labels.


Since this question has a nice google ranking, I'll add what I was originally searching for.

The OP probably was aware that filter needs a predicate that returns a Boolean and that the filter will return a list with the items that pass the predicate (the items which the predicate returned true).

What he was not aware is that we can "emulate" Java returns through Kotlin labels:

private fun findFilteredOrder(courier: Courier) : List<Order> {
    val glovoBoxKeyWords = glovoBoxWords.toLowerCase().split(",")
    val allowedVehicles = listOf(Vehicle.ELECTRIC_SCOOTER, Vehicle.MOTORCYCLE)

    orderList.filter shouldSkip@{ order ->
        val description = order.getDescription().toLowerCase()

        if (courier.getBox()) {
            return@shouldSkip true
        }
        if (glovoBoxKeywords.none { it in description }) {
            return@shouldSkip true
        }
        return@shouldSkip false
    }.filter shouldSkip@ { order ->
        val pickupLocation = order.getPickup()
        val deliveryLocation = order.getDelivery()
        val distance = calculateDistance(deliveryLocation, pickupLocation)

        if (distance <= longDeliveryDistance) {
            return@shouldSkip true
        }
        if (courier.getVehicle() in allowedVehicles) {
            return@shouldSkip true
        }
        return@shouldSkip false
    }
}

Since Kotlin allows us to return in the last block line and the return keyword returns to the outer scope, it is pretty easy to:

filter {
    startPutting >= someMagic && andComplex || 
      verificationsThat.is { hardToUnderstand }.because {
        weNeedToReturnHere
      }
}

The labels allow us to be more verbose but also more clear.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.