I hope you are very well, I wanted to ask you what other option I would have to reduce this "bad practice", of nested conditionals, I have the following function
var Internet = "1";
var Tv = "1";
var Linea = "1";
var DTv = "1";
function probabilidades(Internet, Tv, Linea, DTv) {
Internet = parseInt(Internet);
Tv = parseInt(Tv);
Linea = parseInt(Linea);
DTv= parseInt(DirecTV);
if(Linea && Tv && Internet == 1){
return 1
}
else if(Linea && Tv && Internet && DTv == 1){
return 2
}
else if(Linea && Tv && Internet == 1){
return 3
}
else if(Linea && Tv && DTv == 1){
return 4
}
else if(Linea && Internet == 1){
return 5
}
else if(Linea && Internet && DTv == 1){
return 6
}
else if(Tv && Internet == 1){
return 7
}
else if(Tv && Internet && DTv == 1){
return 8
}
else if(Linea == 1){
return 9
}
else if(Linea && DTv == 1){
return 10
}
else if(Tv == 1){
return 11
}
else if(Tv && DTv == 1){
return 12
}
else if(Internet == 1){
return 13
}
else if(Internet && DTv == 1){
return 14
}
else if(DTv == 1){
return 15
}
else {
return 0
}
}
If I use one switch
I don't think it would look good either, and I would like to know if you can help me by thinking of something more practical and that it would look much better. I clarify that the variables that I am passing as arguments to the function probabilidades();
can come in 1
or in 0
, so depending on that I apply the conditionals. I would appreciate any help
The shortest answer I can think of (but maybe a bit more complicated to understand) would be this:
Let's put it to the test:
Explanation:
What we are doing is that since you have 4 values that can be 0 or 1, it is a good candidate to be handled together as a single value. As you know numbers can be represented in binary, for example:
We do exactly the same with your 4 variables
Here we achieve that Internet is the bit on the left, Tv the bit that follows, Linea the bit that follows and DTv the bit that follows.
All those together will give a single number according to their combination (From 0 to 15)
We then use that position in a predefined array that tells us what should return that combination.
So if we have
Internet=1
,Tv=1
,Linea=1
andDTv=1
according to your conditionals it should return 2. Converting those 4 values into a single number with bits gives us the value 15. Which means that in position 15 of the array we put the 2.(And so on with the others I filled the array).
Now the only thing that is enough is that the function returns what all the data together should return.
return respuestasSegunValorConjunto[valorConjunto];
Note: There is a null value in the array, but it is the one that corresponds in your example to the IF that is repeated. When you correct it you will know what value to put there.
Greetings.
As you have already been told in the comments, the switch with a boolean value is ideal for this type of structure (at least from my point of view).
Even so, the logic that you use in the if is not correct, since many cases will never be fulfilled.
This is what switch would look like with your current order of conditionals:
Look at the comments I have made and the cases that will never be fulfilled because you order it incorrectly. First you must put the cases that have more elements involved.
This would be better, since all cases are achievable (except 3, which is repeated):
I have taken two unorthodox licenses: 1) Not using the
break
becausereturn
it would prevent me from reaching it and 2) I have put each case on a line to shorten lines and make it look more compact.It's not that it looks much better but you can define a function that returns an object with the different combinations. Something like this:
Although you already have 3 answers, I think what you could do is simply create a string with the values of each variable and parse it as a binary value.
Since each parameter takes the value of a
bit
, it is simply a matter of converting its binary representation of the set (4 bits) into a decimal value, which is what you are trying to return in your function.With 4 bits you can represent decimal values from 0 to 15, and that is precisely the expected result of your function. To convert a string representing a binary value to a decimal you can use the method
parseInt(cadena, 2)
, which receives a string and the number base it represents. This method will return the decimal value of the received string.For example:
You must take into account the order in which the arguments are passed, since the result obtained depends on this.
Analyzing the condition that you have associated to the values that you can return, it is clear that there is no direct relationship between the returned value and its binary representation. You may need to consider exactly the priorities or use cases of those values, as well as their position within the bit string. These business rules only you know. But taking into account the name of the function, you are trying to weight from 0 to 15 the value assignment to the received arguments.
As for your formulation, the way to write this conditional is incorrect:
If in that condition you mean if Line, Tv and Internet are equal to 1 , the condition should really be written like this:
There is a big difference between the two, since in javascript there is the concept of
truthy
andfalsy
and it refers to the way values are interpreted in a boolean context.In your condition Linea and TV do not necessarily have a value of 1, so even if they take another value than those considered,
falsy
then the condition will be met.I hope this helps you solve the problem.