Reputation: 1561
I have the following code in Java:
public void doSomething(int i) {
if (i == 12) {
// order should be same
up();
left();
stop();
}
if (i == 304) {
// order should be same
right();
up();
stop();
}
if (i == 962) {
// order should be same
down();
left();
up();
stop();
}
}
// similar code can be done using switch case statements.
// all the function can have any functionality and might not resemble to the name given to them.
Now if I am asked not to use either of if-else and switch case statements, then what can be done? The code can be done in either Java or JavaScript.
Upvotes: 15
Views: 9122
Reputation: 16020
If you can use JavaScript, you can use a object with functions:
function doSomething(i) {
var obj = {};
obj[12] = function () {
// order should be same
up();
left();
stop();
};
obj[304] = function () {
// order should be same
right();
up();
stop();
};
obj[962] = function () {
// order should be same
down();
left();
up();
stop();
};
// apparently we can't use any conditional statements
try {
obj[i]();
} catch (e) {}
}
If only if
and switch
statements aren't allowed, replace all the if
statements with the logical AND operator (&&
):
function doSomething(i) {
(i == 12) && (
// order should be same
up(),
left(),
stop()
);
(i == 304) && (
// order should be same
right(),
up(),
stop()
);
(i == 962) && (
// order should be same
down(),
left(),
up(),
stop()
);
}
Upvotes: 30
Reputation: 121
The desired behavior can be achieved in JAVA by playing with the short-circuit of the logical AND operator as follows:
public static Boolean seq12() {
// order should be same
up();
left();
stop();
return true;
}
public static Boolean seq304() {
// order should be same
right();
up();
stop();
return true;
}
public static Boolean seq962() {
// order should be same
down();
left();
up();
stop();
return true;
}
public static void doSomething(int i) {
Boolean tmp;
tmp = (i == 12 && seq12());
tmp = (i == 304 && seq304());
tmp = (i == 962 && seq962());
}
This code is pretty straight-forward and relies on the fact that the logical AND operator only evaluates the second operand if the first one is true.
Upvotes: 0
Reputation: 684
This problem could be solved using OOP techniques.
In java it would look like this:
public abstract class AObject{
public abstract void doSomething();
public void up(){
//do something here
}
public void down(){
//do something here
}
public void left(){
//do something here
}
public void right(){
//do something here
}
public void stop(){
//do something here
}
}
public class AObject12 extends AObject{
public void doSomething(){
up();
left();
stop();
}
}
public class AObject304 extends AObject{
public void doSomething(){
right();
up();
stop();
}
}
public class AObject962 extends AObject{
public void doSomething(){
down();
left();
up();
stop();
}
}
Executing doSomething on a instance of a concrete class will trigger the appropriate behavior. So no more if/else is necesary. See code below for an example:
AObject A12 = new AObject12();
A12.doSomething();
// Will run Up left stop in that order
AObject A304 = new AObject304();
A304.doSomething();
// Will run right Up stop in that order
AObject A962 = new AObject962();
A962.doSomething();
// Will run down left up stop in that order
Some more info on this kind of programming can be found here: http://en.wikipedia.org/wiki/Polymorphism_%28computer_science%29
If you would like to be able to change the behavior of the object dynamicly you could consider applying a state pattern: http://en.wikipedia.org/wiki/State_pattern
Upvotes: 1
Reputation: 49
Wahahahahaha, you saved my day :) This should work, no way to test right now..
public void doSomething(int i) {
try {
int x = 1/(12-i); // fails for i==12
} catch (ArithmeticException e) {
up();
left();
stop();
}
and so on, enjoy!
Upvotes: 4
Reputation: 272256
Here is a simple way to accomplish this in JavaScript:
function up() { console.log("up"); }
function down() { console.log("down"); }
function left() { console.log("left"); }
function right() { console.log("right"); }
function stop() { console.log("stop"); }
var fnmaps = {
12: [up, left, stop],
304: [right, up, stop],
962: [down, left, up, stop]
};
function doSomething(i) {
var fnmap = fnmaps[i] || [], j;
for (j = 0; j < fnmap.length; j++) {
fnmap[j]();
}
}
doSomething(12);
doSomething(304);
doSomething(962);
Functions can be added/ordered simply by editing the map variable.
Upvotes: 17
Reputation: 5279
In Java, this should work..
public class IfTest {
public static void main(String[] args) {
IfTest ifTest = new IfTest();
ifTest.doSomething(12);
ifTest.doSomeThingWithoutIf(12);
ifTest.doSomething(304);
ifTest.doSomeThingWithoutIf(304);
ifTest.doSomething(962);
ifTest.doSomeThingWithoutIf(962);
ifTest.doSomething(42);
ifTest.doSomeThingWithoutIf(42);
}
public void doSomeThingWithoutIf(int i) {
boolean x = i == 12 ? f12() : (i == 304 ? f304() : (i == 962 ? f962() : false));
}
public boolean f12() {
up();
left();
stop();
return true;
}
public boolean f304() {
right();
up();
stop();
return true;
}
public boolean f962() {
down();
left();
up();
stop();
return true;
}
public void doSomething(int i) {
if(i == 12) {
// order should be same
up();
left();
stop();
}
if(i == 304) {
// order should be same
right();
up();
stop();
}
if(i == 962) {
// order should be same
down();
left();
up();
stop();
}
}
private boolean retfalse() {
return false;
}
private void down() {
System.out.println("down");
}
private void right() {
System.out.println("right");
}
private void stop() {
System.out.println("stop");
}
private void left() {
System.out.println("left");
}
private void up() {
System.out.println("up");
}
}
Upvotes: 0
Reputation: 75
Then do it with while and break, there is no other way without condition check
public void doSomething(int i) {
while(i == 12) {
// order should be same
up();
left();
stop();
break;
}
while(i == 304) {
// order should be same
right();
up();
stop();
break;
}
while(i == 962) {
// order should be same
down();
left();
up();
stop();
break;
}
}
Upvotes: 4
Reputation:
for js u may try this:
// define ur actions here
var actions = {
"12" : function () { up(); left(); stop(); },
"304" : function () { right(); up(); stop(); },
"962" : function () { down(); left(); up(); stop(); }
};
function doSomething(i) {
var fn = actions[i];
try {
fn();
} catch (err) {
console.error(err);
}
}
//
doSomething(12); //invoke here
Upvotes: 2
Reputation: 43391
You can make a dictionary of input-to-action. In Java this would be a Map<Integer, Runnable>
, with, for instance*:
map.put(12, () -> {
up();
left();
stop();
});
Then, you can get the appropriate Runnable
and run it:
Runnable action = map.get(i);
if (action != null) {
action.run();
} else {
// some default action
// This is the "default" case in a switch, or the "else" in an if-else
}
The if-else there isn't strictly necessary, but without it, you'll get a NullPointerException
if i
isn't an expected value — that is, one of the values you put into the map.
The idea is similar in JavaScript, though with objects instead of Map
s, functions (probably anonymous) instead of Runnable
s, etc.
This code is for Java 8. In Java 7 and below, you'd do:
map.put(12, new Runnable() {
@Override
public void run() {
up();
left();
stop();
}
});
Upvotes: 12
Reputation: 7457
Look, naturally you should inspect a conditional statement with a conditional expression! Now, if you don't want to do this, you can do it unnaturally like this:
first do this for all methods (up,down,...)
java.lang.reflect.Method method;
try {
method = obj.getClass().getMethod(methodName, param1.class, param2.class, ..);
} catch (SecurityException e) {
// ...
} catch (NoSuchMethodException e) {
// ...
}
instead of an integer that you pass to the doSomething
, use an array containing name of the methods that you want to call and inside a for loop call each method this way:
Then you invoke that method by calling
try {
method.invoke(obj, arg1, arg2,...);
} catch (IllegalArgumentException e) {
} catch (IllegalAccessException e) {
} catch (InvocationTargetException e) {
Unfortunately Java has not delegates!
Upvotes: 1