Smart Way to Chain Ifelse Statements

Smart way to chain ifelse statements?

Apart from the suggestions in comments you could also use match in the following way.

Create sample data:

set.seed(1)
vals_in <- c("x", "y", "z") # unique values in your input vector
vec_in <- sample(vals_in, 10, replace = TRUE) # sample from vals_in to create input
vals_out <- c("x1", "x2", "x3") # values to replace

Now, to replace the nested ifelses you could do:

vec_out <- vals_out[match(vec_in, vals_in)]

The result is

vec_out
# [1] "x1" "x2" "x2" "x3" "x1" "x3" "x3" "x2" "x2" "x1"

A little comparison of two approaches:

set.seed(1)
vals_in <- letters
vec_in <- sample(vals_in, 1e7, replace = TRUE)
vals_out <- LETTERS

system.time(vals_out[match(vec_in, vals_in)])
User System verstrichen
0.378 0.020 0.398
system.time(unname(setNames(vals_out, vals_in)[vec_in]))
User System verstrichen
1.020 0.062 1.084

What is a SMART WAY to deal with a lot of repeated If statements checks?

Maybe group the same IF condition together?

Here is something that I will recommend:

if ($option == 'Name') {
if ($newoption == 'Email' && !empty($newEmail)) {
//...
}
if ($newoption == 'Age' && !empty($newAge)) {
//...
}
}

A little less repetition:

if ($option == 'Name') {
// use this 'if', if $newoption correlates to which child if is populated...
if ($newoption == 'Email' || $newoption == 'Age') {
if (!empty($newEmail)) {
//...
}
if (!empty($newAge)) {
//...
}
}
}

Chain of OR conditions in if statement

From a purely semantic-syntactical point of view there's no effective difference between them. But if readability is your concern, why don't you use the "datenwolf" formatting style – I came to develop that style over the course of my past 5 projects or so:

if( someFunction1(a)
|| someFunction2(b->b1,c)
|| *d == null
|| somefunction3(e) > f * g
|| !e->e1
|| ...
){
return 0;
} else {
do_something;
}

Do you see how beautiful everything lines up? It really looks like a tube the program is falling down through until it hits a met condition. And if you have && it looks like a chain of operations that must not be broken.

Best practice for large amounts of if/else statements

First off, good job noticing that large if/else statements are not a positive thing. There are a lot of ways to make them less painful and easier to read, some of which you've touched on. For example, you could move this to another class (as you said), or at the very least another method to isolate them from the rest of your code.

One design pattern that I've found helpful in this situation is the chain-of-responsibility pattern. In the CoR pattern, you have a number of command objects that are responsible for knowing if they can handle a particular value. So in your case, you'd have a command object for each if/else in your logic, and each command object would know if they can handle newCondition.number. If the command object can handle the value, it performs its' logic (in your case, it'd perform the stuff inside the if/else); if it cannot, it passes the message along to the next object in the chain.

This has the benefit of isolating the logic and making it easier to add functionality with minimal impact. You can also name the command subclasses something interesting and informative to remove some of the mystique of the code.

At the very least, I'd refactor the if statement into its own method. And if you have lots of if/else statements, I'd consider the chain-of-responsibility pattern.

There is a great book called Refactoring to Patterns that I highly recommend.

Is there a better way to write nested if statements in python?

While @Aryerez and @SencerH.'s answers work, each possible value of numeral_sys_1 has to be repeatedly written for each possible value of numeral_sys_2 when listing the value pairs, making the data structure harder to maintain when the number of possible values increases. You can instead use a nested dict in place of your nested if statements instead:

mapping = {
'Hexadecimal': {'Decimal': 1, 'Binary': 2},
'Binary': {'Decimal': 3, 'Hexadecimal': 5},
'Decimal': {'Hexadecimal': 4, 'Binary': 6}
}
def convert_what(numeral_sys_1, numeral_sys_2):
return mapping.get(numeral_sys_1, {}).get(numeral_sys_2, 0)

Alternatively, you can generate the pairs of values for the mapping with the itertools.permutations method, the order of which follows that of the input sequence:

mapping = dict(zip(permutations(('Hexadecimal', 'Decimal', 'Binary'), r=2), (1, 2, 4, 6, 3, 5)))
def convert_what(numeral_sys_1, numeral_sys_2):
return mapping.get((numeral_sys_1, numeral_sys_2), 0)


Related Topics



Leave a reply



Submit