Home > OS >  How figure out multiple nested if else condition?
How figure out multiple nested if else condition?

Time:05-08

I am not getting the efficient way to check below mentioned condition. What I want to achieve is that- There are some process need to be done if there corresponding boolean is true suggesting to start the process. So I want to check if particular condition is done and only check is it was started.

There are some boolean variables

var shouldStartProcessA
var shouldStartProcessB
var shouldStartProcessC

var isADone
var isBDone
var isCDone

if (shouldStartProcessA && shouldStartProcessB && shouldStartC) {
    if (isADone && isBDone && isCDone) {
        // Every process completed
    }
}

if (shouldStartProcessA && shouldStartProcessB) {
    if (isADone && isBDone) {
        // Every process completed
    }
}

if (shouldStartProcessA && shouldStartC) {
    if (isADone && isCDone) {
        // Every process completed
    }
}

if (shouldStartProcessB && shouldStartC) {
    if (isBDone && isCDone) {
        // Every process completed
    }
}

if (shouldStartProcessA) {
    if (isADone) {
        // Every process completed
    }
}

if (shouldStartProcessB) {
    if (isBDone) {
        // Every process completed
    }
}

if (shouldStartProcessC) {
    if (isCDone) {
        // Every process completed
    }
}

This type of validating condition grows exponentially by introducing every other boolean. I am struggling to find a straightforward implementation to check these conditions.

CodePudding user response:

Instead of doing things this way, I'd recommend a data structure that allows you to add tasks and check their state. There are a lot of ways to do that, but the basic idea is you can iterate over all the items and use functions like all to confirm they're all in the appropriate state. That way you don't have to hand-wire everything together

You could use a Map and add tasks to it, initially mapping them to false and setting that to true when they're completed. Or create a Set and add your tasks to that (I'm assuming you want one of each at most), and remove them / move them to a "done" list when they complete. That kind of idea. You could create an enum class to represent your tasks if you want, so each one is its own instance (e.g. Process.A, like having a dedicated, fixed variable) and you can easily use those in your logic


If you really want variables for each process, instead of a data structure, I'd still recommend rolling each pair into a single state, something like this:

enum class State {
    UNUSED, PENDING, DONE
}

var processA = State.UNUSED
var processB = State.PENDING
// etc

// you can easily check them like this:

// create a list of all the variables you want to check - we're using references
// to the properties themselves (with the ::), not the current value!
val allProcesses = listOf(::processA, ::processB)

// now you have that collection, you can easily iterate over them all
// and work out what's what - we need to use get() to get the current values
val allFinished = allProcesses
    .filterNot { it.get() == State.UNUSED } // ignore unused processes
    .all { it.get() == State.DONE } // check ALL the required ones are DONE

You could write that check there as a single all condition, but the point is to show you you can be flexible with it, and build up your logic by filtering out the stuff you're not interested in, if you create a useful set of states


If you really do want to (or have to) stick with the current "pairs of variables" setup, you can do something similar:

// wiring them up again, creating a list of Pairs so we can iterate over them easily
val allProcesses = listOf(
    ::shouldStartProcessA to ::isADone,
    ::shouldStartProcessB to ::isBDone,
    ::shouldStartProcessC to ::isCDone
)

// gotta check 'em all - only returns true if that ALL meet the condition
val allComplete = allProcesses.all { (shouldStart, isDone) ->
    // the get() syntax is awkward, but basically for everything we're checking
    // if it either doesn't need to start, or it does but it's also done
    !shouldStart.get() || (shouldStart.get() && isDone.get())
}

so adding new processes is just a case of adding their variables to the list of pairs, and they get included in the checking


You don't need the property reference stuff (::/.get()) if you create the lists right before you check them, but if you want to define them once in advance (and the property values can change after that) then that's how you'd do it. Otherwise you can just do the normal shouldStartProcessA to isADone etc, which is probably fine for most cases - I'm showing the reference stuff as a more general example for handling this kind of thing

CodePudding user response:

I suppose, you should create two lists of Boolean and add variables consequently.

val list1 = listOf(shouldStartProcessA, shouldStartProcessB, shouldStartC)
val list2 = listOf(isADone, isBDone, isCDone)

Then iterate over both lists and check that items in corresponding positions have the same values.

var n = 0
for (i in list1.indices) {
   if (list1[i] == list2[i]) {
       n  
   } else {
       n = 0
       break
   }
}

if (n > 0) {
    // Every process completed
}
  • Related