How to Avoid "If" Chains

How to avoid if / else if chain when classifying a heading into 8 directions?

#include <iostream>

enum Direction { UP, UP_RIGHT, RIGHT, DOWN_RIGHT, DOWN, DOWN_LEFT, LEFT, UP_LEFT };

Direction GetDirectionForAngle(int angle)
{
const Direction slices[] = { RIGHT, UP_RIGHT, UP, UP, UP_LEFT, LEFT, LEFT, DOWN_LEFT, DOWN, DOWN, DOWN_RIGHT, RIGHT };
return slices[(((angle % 360) + 360) % 360) / 30];
}

int main()
{
// This is just a test case that covers all the possible directions
for (int i = 15; i < 360; i += 30)
std::cout << GetDirectionForAngle(i) << ' ';

return 0;
}

This is how I would do it. (As per my previous comment).

How to avoid multiple chain of if else

You can use a pointer to pointer and a loop:

const char *ap[] = {"some", "some1", "some2", "some3", NULL};
const char **p = ap;

while (*p) {
if (strcmp(somename, *p) == 0) {
fun();
break;
}
p++;
}

How to avoid nested chains of if let ?

There's an unstable feature that will introduce let-else statements.

RFC 3137

Introduce a new let PATTERN: TYPE = EXPRESSION else DIVERGING_BLOCK; construct (informally called a let-else statement), the counterpart of if-let expressions.

If the pattern match from the assigned expression succeeds, its bindings are introduced into the surrounding scope. If it does not succeed, it must diverge (return !, e.g. return or break).

With this feature you'll be able to write:

let Some(i) = func1() else {
println!("func 1 returned None");
return;
};
let Some(j) = func2(i) else {
println!("func 2 returned None");
return;
};
let Some(k) = func3(j) else {
println!("func 3 returned None");
return;
};
let Some(result) = func3(k) else {
println!("func 4 returned None");
return;
};

If you want to try it out now, use:

#![feature(let_else)]

How to remove large if-else-if chain

You can extract the code in each branch to a separate method, then turn the methods into implementations of a common base interface (let's call it Handler). After that, you can fill a Map<String, Handler> and just look up and execute the right handler for given string.

Unfortunately the implementation of 100+ subclasses for the interface requires quite a lot of boilerplate code, but currently there is no simpler way in Java to achieve this. Implementing the cases as elements of an Enum may help somewhat - here is an example. The ideal solution would be using closures / lambdas, but alas we have to wait till Java 8 for that...

How to avoid long chain of free's (or deletes) after every error check in C?

You could define a new label that would free the resources and then you could GOTO it whenever your code fails.

char* function()
{
char* retval = NULL;
char* mem = get_memory(100); // first allocation
if (!mem)
goto out_error;

struct binder* b = get_binder('regular binder'); // second allocation
if (!b)
goto out_error_mem;

struct file* f = mk_file(); // third allocation
if (!f)
goto out_error_b;

/* ... Normal code path ... */
retval = good_value;

out_error_b:
free_binder(b);
out_error_mem:
free(mem);
out_error:
return retval;
}

Error management with GOTO was already discussed here:
Valid use of goto for error management in C?

How to avoid a lot of if else conditions

Try to look at the strategy pattern.

  • Make an interface class for handling the responses (IMyResponse)

    • Use this IMyResponse to create AdvisoryBoardResponse, EditorialBoardResponse classes
  • Create an dictionary with the soapresponse value as key and your strategy as value
  • Then you can use the methods of the IMyResponse class by getting it from the dictionary

Little Example:

// Interface
public interface IResponseHandler {
public void handleResponse(XmlPullParser xxp);

}

// Concrete class for EditorialOffice response
private class EditorialOfficeHandler implements IResponseHandler {
public void handleResponse(XmlPullParser xxp) {
// Do something to handle Editorial Office response
}
}

// Concrete class for EditorialBoard response
private class EditorialBoardHandler implements IResponseHandler {
public void handleResponse(XmlPullParser xxp) {
// Do something to handle Editorial Board response
}
}

On a place you need to create the handlers:

Map<String, IResponseHandler> strategyHandlers = new HashMap<String,IResponseHandler>();
strategyHandlers.put("EditorialOffice", new EditorialOfficeHandler());
strategyHandlers.put("EditorialBoard", new EditorialBoardHandler());

Where you received the response:

IResponseHandler responseHandler = strategyHandlers.get(soapResponse);
responseHandler.handleResponse(xxp);


Related Topics



Leave a reply



Submit