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 ifelse
s 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
Plot Title at Bottom of Plot Using Ggplot2
From Long to Wide Data with Multiple Columns
Combine/Merge Columns While Avoiding Na
How to Find the Package Name in R for a Specific Function
Pass R Variable to Rodbc's SQLquery with Multiple Entries
Number of Rows Each Data Frame in a List
Tidyr::Pivot_Wider() Reorder Column Names Grouping by 'Name_From'
How to Place Legends at Different Sides of Plot (Bottom and Right Side) with Ggplot2
How to Save the Wordcloud in R
Repeat Vector to Fill Down Column in Data Frame
Are Eigenvectors Returned by R Function Eigen() Wrong
How to Calculate a Table of Pairwise Counts from Long-Form Data Frame
R // Sum by Based on Date Range
Accessing Parent Namespace Inside a Shiny Module
Cannot Read File with "#" and Space Using Read.Table or Read.CSV in R
Force Facet_Wrap to Fill Bottom Row (And Leave Any "Gaps" in the Top Row)