views:

244

answers:

8

Hi Guys,

Trying not to repeat myself (to be DRY) here, help me out. =)

I have a double which represents a rating / 5.

The possible values are:

0, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5, 5.

I want to convert this to a string without the decimal place.

So the values would become:

"0", "05", "1", "15", "2", "25", "3", "35", "4", "45", "5".

Why am i doing this? Because i'm trying to dynamically create a link based on the value:

string link = "http://somewhere.com/images/rating_{0}.gif";
return string.Format(link, "15");

The possible values are handled/validated elsewhere, in other words i can be 100% sure the value will always be one of those i mentioned.

Any ideas? Some special format i can use in the .ToString() method? Or am i stuck with an un-DRY switch statement? Or can i cheekily do a decimal.ToString().Replace(".","")?

EDIT:

Whoah, thanks for all the answers guys! =)

Most answers are correct, so i'll leave this open for a day or so and pick the answer with the most votes.

Anyway, i ended up creating a simple extension method:

public static string ToRatingImageLink(this decimal value)
    {
        string imageLinkFormat = "http://somewhere.com/images/rating_{0}.gif";
        return string.Format(imageLinkFormat, value.ToString().Replace(".0", string.Empty).Replace(".", string.Empty);
    }

Guess it was a case of "KISS" and "DRY". In this case the syntactic sugar of extension methods kept it DRY, and and the actual one-line implementation satisfies KISS.

+2  A: 

I would just use the "cheekily" method you describe at the end. In pure semantics of the thing, you're manipulating a string, not the actual number, so I think a string replacement would be exactly the correct prescription here.

If you really want to overcomplicate it, consider creating a new IFormatProvider for this situation. This would be a better way of catching potential errors, but it adds a layer of complexity.

drharris
A: 

You could call ToString(), and then use a regular expression like replacing "([0-9])\\.([0-9])" with "\\1\\2", which, although still a bit of a hack, would be less fragile than Replace(".","")

This seems like a lot of overhead if he controls both ends of the conversion, which it appears like he does.
codekaizen
As i said in the question, i can be sure of the format of the double, as there is an existing extension method which rounds to the nearest half. I was hoping for a secondary extension method which returns the string. ie double.RoundToNearestHalf().ToImageLink().
RPM1984
As much as I like regular expressions (and I do), .net can handle it better. Still, something like `Regex.Replace("1.5", @"\D", "")` is probably more robust, your regex makes specific assumptions as to the format of the string.
Kobi
+1  A: 

Use a hashtable/dictionary and keep mappings from double to string in there. That will be much more robust and simpler than parsing your double

Nitin Chaudhari
What's the difference between that and a hard coded switch/if else statement? Only difference is being able to do a lookup, but the actual code which still need to be hard coded (ie items.Add(0.5, "05"))
RPM1984
A hashtable could potentially increase performance if you're dealing with larger lookup tables, but for as small a list as your example you'd be better off with a giant switch statement.
drharris
True, and if there is a direct simple way to do it, then sure we should not use a dictionary. However if I had to parse and put some string manipulation logic then i would avoid that simply because that is error prone.
Nitin Chaudhari
A dictionary is overkill. You could do this with an array.
finnw
+5  A: 

Decimal delimiter depends on current culture preferences:

d.Replace(
    System.Globalization.CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator,
    String.Empty)

will replace '.' or ',' with ""

abatishchev
It's probably easier to use a CultureInfo when converting the number to string, as suggested by other answers. Then you *know* the string format, and can simply replace the dot.
Kobi
@Kobi: Yes, when you know and absolutely sure that delimiter is dot not comma. Dynamic delimiter is very easy to use, minimizes strings hardcoding and very intelligent as OP asked
abatishchev
+3  A: 

If you could live with strings like 00, 05, 10, 15, 20 ... etc., you could simply use

(rating * 10).ToString("00")

If not, use InvariantCulture as argument to ToString in order to force the use of a decimal point (".") in all countries (in Germany the default would be "," for example):

rating.ToString(CultureInfo.InvariantCulture).Replace(".","");
MartinStettner
`Replace(".", "")` does seem like the best way.
Kobi
A: 

Don't try to find a simpler answer to something that's already simple. The easiest way to do it is to use this code:

double dblNumber = 1.5;
string strDouble = dblNumber.ToString("N1").Replace(".","").Trim('0');

If it is something you are going to be doing a lot, wrap it in a function:

string ConvertToString(double dblNumber)
{
    return dblNumber.ToString("N1").Replace(".","").Trim('0');
}
icemanind
I thought about `TrimEnd`, but keep in mind it turns `0` to `""`. `Trim` also turns `05` to `5`, which is wrong.
Kobi
The `Trim('0')` part is incorrect. There could never be a "0" output ...
MartinStettner
+2  A: 

you can just use Replace(".", string.Empty); with no need for Replace(".0", string.Empty)

check the below code

double[] x = { 0.0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 5.5 };
            foreach (var item in x)
            {
                listBox1.Items.Add(item.ToString().Replace(".", string.Empty));
            }

the result will be alt text

Space Cracker
+1 for taking the time to try out your answer and showing the proof of it working.
RPM1984
+1  A: 

To avoid messing with decimal formats, I would format the whole part as an integer and use an array lookup for the fractional part:

public static string ToRatingImageLink(this decimal value)
{
    string imageLinkFormat = "http://somewhere.com/images/rating_{0}{1}.gif";
    int index = decimal.ToInt32(decimal.Round(value * 2));
    return string.Format(imageLinkFormat, index / 2, Suffix[index % 2]);
}

static readonly string[] Suffix = { "", "5" };
finnw