Reputation: 124
I am building a function which verifies a user's input makes sense in context of the application before it runs a block of code. I'm wondering whether an "if...else" statement like this or a switch statement is going to work more reliably/otherwise be a better solution? I lean toward if...else because I only have two outcomes--the user's input is either valid or tell the user what the program will accept, but I would like advice from somebody more experienced before I get too involved.
edit: For clarity, I only want my code to execute when i and o are both either "a" or "b", or both either "c" or "d", or both either "e" or "f".
console.log("i="+i+" o="+o);
if
(((i == ("a" || "b")) && (o == ("a" || "b")))
|| ((i == ("c" || "d")) && (o == ("c" || "d")))
|| ((i == ("e" || "f")) && (o == ("e" || "f"))))
{
//my block here
}
else
{
//tell the user their input doesn't make sense
}
Also, am I handling my Boolean operators correctly in this case?
Upvotes: 3
Views: 112
Reputation: 28417
You could also do this:
var i='a', o='b',
allowed = [['a','b'], ['c', 'd'], ['e', 'f']];
function test(one, two) {
return allowed.some(function(elem) {
return (elem.indexOf(one)>=0 && elem.indexOf(two)>=0);
});
}
console.log(test(i, o));
Have an array of all of your allowed value pairs, and then use Array.prototype.some() to test if your i
and o
are within the allowed values. .some()
will execute the callback function once for each element present in the array until it finds one where callback returns a true value. If such an element is found, it immediately returns true.
Here is a snippet:
// Only for this snippet
console.log = function(txt) {
var result = document.getElementById("result");
result.innerText += txt + ", ";
}
// allowed values
var i, o, allowed = [['a','b'], ['c', 'd'], ['e', 'f']];
// function to test
function test(one, two) {
return allowed.some(function(elem) {
return (elem.indexOf(one)>=0 && elem.indexOf(two)>=0);
});
}
// all tests
i = 'a'; o = 'b';
console.log(test(i, o));
i = 'c'; o = 'd';
console.log(test(i, o));
i = 'e'; o = 'f';
console.log(test(i, o));
i = 'a'; o = 'c';
console.log(test(i, o));
i = 'd'; o = 'e';
console.log(test(i, o));
i = 'x'; o = 'y';
console.log(test(i, o));
<p id="result"></p>
And a fiddle to play with: http://jsfiddle.net/abhitalks/sfuxv4ov/
Upvotes: 1
Reputation: 388406
Instead of using so many or...and block which could make it unreadable, you can try a simple solution like below.
In this solution we first create a map of allowed values, and for each values what are the allowed combination for the second variable, then we check whether the value of a
exists in the map, if so then we check whether the value of i
is a permitted value in the allowed combination
function test(a, i) {
var map = {
a: ['a', 'b'],
b: ['a', 'b'],
c: ['c', 'd'],
d: ['c', 'd'],
e: ['e', 'f'],
f: ['e', 'f']
};
if (map[a] && map[a].indexOf(i) > -1) {
console.log('found', a, i, result === true)
} else {
console.log('not found', a, i, result === false)
}
}
Upvotes: 4
Reputation: 17071
First, your Javascript doesn't work because non-empty strings evaluate to true
, so ("c" || "d")
just evaluates to "c". Meaning all you're currently checking is that i
and o
are the same value.
Indeed, this actually covers half of the cases that you need (if i
and o
are equal, you definitely proceed, regardless of whether they are "a"
, "b"
, etc).
The logic you want is this:
if( ((i == "a" || i == "b") && (o == "a" || o == "b")) ||
((i == "c" || i == "d") && (o == "c" || o == "d")) ||
((i == "e" || i == "f") && (o == "e" || o == "f"))
){
// valid
} else {
// invalid
}
I prefer that kind of if
statement to the convoluted switch
that you might end up with.
You could also approach it this way. You realize that i
and o
can be no more than one letter off from one another, so you can write this kind of logic:
if( Math.abs(i.charCodeAt(0) - o.charCodeAt(0)) <= 1 ){
// valid
} else {
// invalid
}
This is saying that as long as i
and o
are either the same letter or no more than one apart (using their ASCII values to compare), it's valid. Here's a demo.
check("a", "a")
// true
check("a", "b")
// true
check("a", "c")
// false
check("e", "f")
// true
check("a", "a")
// true
check("b", "a")
// true
Upvotes: 3
Reputation: 35491
Firstly, your if
statement is wrong because JavaScript boolean expressions get coerced to boolean values.
Meaning:
'a' || 'b'
Will always return 'a'
because 'a'
evaluates to true
and the JS engine has no need to check the second operand of the ||
statement.
So your if
statement should look like:
if(((i == "a" || i == "b") && (o == "a" || o == "b")) ||
((i == "c" || i == "d") && (o == "c" || o == "d")) ||
((i == "e" || i == "f") && (o == "e" || o == "f"))
Upvotes: 4