WISHY
WISHY

Reputation: 11999

Find 2 elements in list and return true kotlin?

I have list and I need to check whether it contains 2 specific string or not. I have the below code and looking to optimise it further

fun isContentTVE_AVOD(subscriptionPlans: List<ContentDatum>): Boolean {
    var tve = false
    var avod = false
    if (subscriptionPlans.size > 0) {
        for (i in subscriptionPlans.indices) {
            if (subscriptionPlans[i] != null &&
                    subscriptionPlans[i].planMonetizationModel != null) {
                if (subscriptionPlans[i].planMonetizationModel.equals("TVE", ignoreCase = true)) tve = true
                if (subscriptionPlans[i].planMonetizationModel.equals("AVOD", ignoreCase = true)) avod = true
            }
        }
    }
    return tve && avod
}

Upvotes: 1

Views: 579

Answers (4)

gidds
gidds

Reputation: 18547

What are you trying to optimise for?

My natural reaction would be to start with the simplest code, which is along the lines of:

fun isContentTVE_AVOD(subscriptionPlans: List<ContentDatum>)
    = "TVE" in subscriptionPlans
    && "AVOD" in subscriptionPlans

That's simple, easy to read and understand (pretty close to how you'd describe the function), and hard to get wrong.  So it'll save you time — and whoever has to debug and maintain and enhance your code.  It's usually far better to keep things simple wherever possible.

It's also likely to be a little faster than your implementation.  Partly because the two in checks will stop when they find a match, rather than continuing along the rest of the list.  But partly because it's simpler — not just your code, but the library routines it's calling will be simpler, so the runtime will have more scope to optimise them.  And also because they'll be called more often, so the runtime will have more opportunity to optimise them.  (The JVM can do a lot of optimisation, perhaps better than you can.  It's usually better to keep your code clear and straightforward to give it the best chance.)

If you think you need it to be faster still, then the first thing would be to do some performance testing, to show whether time spent in that function is really making that much difference to your overall runtime.  (Which seems pretty unlikely in the vast majority of cases.)

If you've shown that that function really is a bottleneck, then tweaking the implementation probably isn't going to gain very much.  However it works, you'll still need to scan through most of the list, on average, making it O(n) — and that complexity will usually outweigh any constant-factor improvements.

So if you do spend a lot of time in that function, then I'd try to change the design, not the implementation.

For example, if you made your subscriptionPlans a Set instead of a List, then you could probably do a lookup in constant time without iterating through the list at all.  (And the code above would work just the same with, except for changing the type!)

Or if you need a list (to preserve the order and/or duplicates), you could use a custom list wrapper which maintained counts of the two values, and updated them when adding/modifying/removing items from the list.  Obviously that would be most appropriate if you make these checks more often than you modify the list (and known in advance which values you'll be checking for).

Upvotes: 2

Kaveri
Kaveri

Reputation: 1088

If it is repeated process or use-case.

Try this:-

Time Complexity :- O(1).

If you list consists of a custom objects, as it appears here, you can try managing the count inside the model class while you are creating the object or while setting the various features and simultaneously increment the count whenever the match is found.

Upvotes: 0

Shalu T D
Shalu T D

Reputation: 4039

You can use find,any or filter methods. Please check below for any method applied:

 fun isContentTVE_AVOD(subscriptionPlans: List<ContentDatum>): Boolean {
    var tve = subscriptionPlans.any { it.planMonetizationModel?.equals("TVE") }
    var avod = subscriptionPlans.any { it.planMonetizationModel?.equals("AVOD") }
    return tve && avod
}

Upvotes: 3

Joel Wiklund
Joel Wiklund

Reputation: 1875

fun isContentTVE_AVOD(subscriptionPlans: List<ContentDatum>): Boolean {
    var tve = false
    var avod = false
    if (subscriptionPlans.size > 0) {
        for (i in subscriptionPlans.indices) {
            if (subscriptionPlans[i] != null &&
                    subscriptionPlans[i].planMonetizationModel != null) {
                if (subscriptionPlans[i].planMonetizationModel.equals("TVE", ignoreCase = true) && subscriptionPlans[i].planMonetizationModel.equals("AVOD", ignoreCase = true)) {
                return true;
                 }
            }
        }
    }
    return false;
}

Upvotes: 0

Related Questions