Is there a popular idiom for a switch statement that takes a string? I
want to emulate something roughly like:
switch (myString) {
case "Apr":
case "Jun":
case "Sep":
case "Nov":
System.out.println("30 days");
break;
case "Feb":
// We need some extra information here
break;
default:
System.out.println("31 days");
}
Lasse Reichstein Nielsen - 26 Jun 2006 17:00 GMT
> Is there a popular idiom for a switch statement that takes a string?
Lots of if-else-if's would do it.
A better approach would be to not use strings to represent meaningfull
values. Parse them into a real representation of the concept you are
working with once and for all, instead of having to read through the
string every time it is used.
In this example, you are using three letter strings to represent
months. Instead, you could have a Month enum, or you could use a
number. Either of these can be used in a switch (but with an enum,
it would be better to have the objects know the month's length
itself).
/L

Signature
Lasse Reichstein Nielsen - lrn@hotpop.com
DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleDOM.html>
'Faith without judgement merely degrades the spirit divine.'
Stefan Ram - 26 Jun 2006 17:01 GMT
>Is there a popular idiom for a switch statement that takes a string?
>I want to emulate something roughly like:
>switch (myString) { case "Apr":
You might want to learn about perfect hash functions
Then calculate a perfect hash value for the string
variable and the constant strings.
(A normal hash function should also do, but »myString.hash()«
might return different hash values for different Java
implementations, so a specific hash function should be used.)
Stefan Ram - 26 Jun 2006 17:15 GMT
> (A normal hash function should also do, but »myString.hash()«
I meant »myString.hashCode()«. But you still would have to use
»equals« unless it is known that the value of the string is
restricted to a small known set (i.e., the 12 months), so it
might be better to use a hash map instead if the value is
not restricted.
A direct translation would be:
map.put( "Apr", new java.lang.Runnable()
{ public void run(){ System.out.println("30 days"); }});
But it might be better to use:
map.put( "Apr", 30 );
bob_jenkins@burtleburtle.net - 26 Jun 2006 19:06 GMT
> You might want to learn about perfect hash functions
> Then calculate a perfect hash value for the string
> variable and the constant strings.
I wish they'd build this into the language. It can be done manually,
but I don't see how to do it manually without it being painful in
comparison to having it built in.
Patricia Shanahan - 26 Jun 2006 19:58 GMT
>> You might want to learn about perfect hash functions
>> Then calculate a perfect hash value for the string
[quoted text clipped - 3 lines]
> but I don't see how to do it manually without it being painful in
> comparison to having it built in.
I haven't tried to use perfect hashes in practice, so I don't know all
the catches. Have you tried e.g. GGPerf?
Patricia
Boris Stumm - 26 Jun 2006 17:38 GMT
> Is there a popular idiom for a switch statement that takes a string? I
> want to emulate something roughly like:
[quoted text clipped - 12 lines]
> System.out.println("31 days");
> }
You can try Enums:
enum month { Jan, Feb, ...};
and then:
switch(Month.valueOf("XXX")) {
case Jan:
case Feb:
...
}
Stefan Ram - 26 Jun 2006 17:51 GMT
>Is there a popular idiom for a switch statement that takes a string? I
>want to emulate something roughly like:
>switch (myString) {
> case "Apr":
This might not be popular this way, but might allow a fast and small
switch table. It uses a perfect hash for "Jan" .. "Dec".
public class Main
{
int[] v;
public Main()
{ v = new int[ 256 ]; for( int i = 0; i < 256; ++i )v[ i ]=15;
v[ 97 ]= 0; v[ 98 ]= 9; v[ 99 ]= 4; v[ 101 ]= 2; v[ 103 ]= 9;
v[ 108 ]= 8; v[ 110 ]= 2; v[ 111 ]= 4; v[ 112 ]= 3; v[ 114 ]= 1;
v[ 116 ]= 3; v[ 117 ]= 1; v[ 118 ]= 4; v[ 121 ]= 0; }
int hash( final java.lang.String s )
{ return v[ s.charAt( 1 )]+v[ s.charAt( 2 )] ; }
void show( final java.lang.String s )
{ switch ( hash( s ))
{ case 4: case 3: case 5: case 8:
java.lang.System.out.println( 30 ); break;
case 11: break;
default: java.lang.System.out.println( 31 ); break; }}
public static void main( final java.lang.String[] args )
{ new Main().show( "Jun" ); new Main().show( "Oct" ); }}
It prints:
30
31