views:

330

answers:

7

I am coding a method that returns whether a given character is valid, which looks like this: -

private static boolean isValid(char c) {
    return c == '.' || c == ',' || c == '+' || c == '/' || c == ';' || c == ':';
}

Check style flagged this up as the boolean complexity is too great (5 when it should be no more than 3). My development manager has flagged up a few alternative implementations which I will post as answers. Personally, I think my code is readable enough and would prefer to turn off check style for this method.

What do you think?

+11  A: 
private static boolean isValid(char c) {
    String validChars =".,+/;:";
    return (validChars.indexOf(c) > -1);
}
Tarski
This is an ok solution, but it does not scale well. For that, you need a lookup table.
Steven Sudit
I'd extract what's a valid character into a property file so you don't have to recompile the code to change the list of valid characters.
Chris Kessel
+5  A: 
private static boolean isValid(char c) {
    switch (c) {
    case '.' : // FALLTHROUGH
    case ',' : // FALLTHROUGH
    case '+' : // FALLTHROUGH
    case '/' : // FALLTHROUGH
    case ';' : // FALLTHROUGH
    case ':' :
      return true;
    default : return false;
    }
}
Tarski
In the case of alternative case statements, I wouldn't bother with the //FALLTHROUGH comments.
Avi
I like this one the best because it's the simplest. If speed is not an issue I ALWAYS go for readiblity because you never know who is going to have to maintain your code when you are not around.
Ben
I quite dislike this one because it's bulky and inflexible.
Steven Sudit
+1  A: 
private static boolean isValid(char c) {
    char[] validChars2 = {'.', ',', '+', '/', ';', ':'};
    for (char d : validChars2) {
      if (c == d) { return true; }
    }
    return false;
}
Tarski
+2  A: 
private static boolean isValid(char c) {
    /* CHECKSTYLE:OFF */
    return c == '.' || c == ',' || c == '+' || c == '/' || c == ';' || c == ':';
    /* CHECKSTYLE:ON */
}
Tarski
A: 

Regular expression could work well. I've hard-coded it into the example below, but you could just as easily pull it out of a config file.

 [Test]
 public void AisNotValid ()
 {
  Assert.IsFalse(IsValid('a'));
 }

 [Test]
 public void SemiColonIsValid ()
 {
  Assert.IsTrue(IsValid(';'));
 }

 public bool IsValid(Char c)
 {
  return Regex.IsMatch(Regex.Escape(".,+/;:"), c.ToString());
 }

The Regex.Escape() method comes in handy here because it escapes characters that normally have meaning in a Regex. From the docs: "Escapes a minimal set of characters (\, *, +, ?, |, {, [, (,), ^, $,., #, and white space) by replacing them with their escape codes."

RKitson
I'm coding in Java, not C#
Tarski
Nice, down-voted for using a different (but VERY similar) language? Weak.
RKitson
I might downvote on the basis of regexp being overkill, but C# is so similar to Java that I didn't even notice.
Steven Sudit
A: 

If readability is not a concern, this can be dealt with a semi binary search, with boolean complexity of 3

As a reference for char values

+ 11
, 12
. 14
/ 15
: 26
; 27

private static boolean isValid(char c)
{
    return c > 14 ? c == '/' || c == ';' || c == ':' : c == '.' || c == ',' || c == '+';
}
Bill Yang
Binary searches are often faster than linear, but for so few elements, the overhead of the more sophisticated algorithm may well not be worth it. A simple look-up table would be faster, and would remain fast no matter how many characters were being tested for.
Steven Sudit
+2  A: 

I'd use a Set. It has the benefit of having a descriptive name, and it scales well.

private static Set<Character> validCharacters = new HashSet<Character>();

public static void initValidCharacters() {
    validCharacters.add('.');
    validCharacters.add(',');
    validCharacters.add('+');
    validCharacters.add('/');
    validCharacters.add(';');
    validCharacters.add(':');
}

private static boolean isValid(char c) {
    return validCharacters.contains(c);
}
Buhb
This would work, the only downside would be the auto-boxing overhead on each check?
BenM