2010-07-26 16 views
11

Versuche, mich nicht zu wiederholen (um DRY zu sein) hier, hilf mir. =)Wie man ein Double intelligent und sicher in String konvertiert?

Ich habe ein Doppel, die ein Rating repräsentiert/5.

Die möglichen Werte sind:

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

ich ohne die Dezimalstelle dies zu einer String konvertieren möchten.

So würden die Werte werden:

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

, warum ich das tue? Weil ich versuche, um dynamisch einen Link zu erstellen basierend auf dem Wert:

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

Die möglichen Werte werden behandelt/anderswo validiert, also kann ich 100% sicher sein, der Wert immer einer von denen sein, werde ich erwähnt .

Irgendwelche Ideen? Einige spezielle Formate, die ich in der .ToString() Methode verwenden kann? Oder bleibe ich bei einer un-DRY-switch-Anweisung stecken? Oder kann ich einen decimal.ToString().Replace(".","") frech machen?

EDIT:

Whoah, danke für alle Antworten Jungs! =)

Die meisten Antworten sind korrekt, also lasse ich das für einen Tag oder so offen und wähle die Antwort mit den meisten Stimmen.

Wie dem auch sei, endete ich eine einfache Erweiterung Methode der Erstellung bis:

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); 
    } 

Vermutung ist es ein Fall von „KISS“ und „trocken“ war. In diesem Fall behielt der syntaktische Zucker der Erweiterungsmethoden DRY bei, und die tatsächliche Ein-Zeilen-Implementierung erfüllt KISS.

+0

Ich habe versucht, einen 'NumberFormatInfo' erstellen, aber ich get 'Dezimaltrennzeichen kann nicht die leere Zeichenkette sein. Schande. – Kobi

+1

+1 für die Frage gut strukturierte Frage – hydrogen

Antwort

9

Dezimaltrennzeichen hängt von aktuellen Kultur Vorlieben:

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

ersetzt '.' oder ',' mit ""

+1

Es ist wahrscheinlich einfacher, eine CultureInfo zu verwenden, wenn Sie die Zahl in eine Zeichenfolge umwandeln, wie von anderen Antworten vorgeschlagen. Dann * kennst du * das String-Format und kannst den Punkt einfach ersetzen. – Kobi

+0

@Kobi: Ja, wenn Sie wissen und absolut sicher, dass Trennzeichen Punkt nicht Komma ist.Das dynamische Trennzeichen ist sehr einfach zu verwenden, minimiert die String-Hardcodierung und ist sehr intelligent, da OP gefragt – abatishchev

2

Ich würde nur die "frech" -Methode verwenden, die Sie am Ende beschreiben. In der reinen Semantik des Dings manipulierst du einen String, nicht die tatsächliche Zahl, also denke ich, dass ein String-Ersatz genau das richtige Rezept wäre.

Wenn Sie es wirklich zu kompliziert machen möchten, sollten Sie eine neue IFormatProvider für diese Situation erstellen. Dies wäre ein besserer Weg, potenzielle Fehler zu erkennen, aber es fügt eine Ebene der Komplexität hinzu.

0

Sie könnten ToString() nennen, und dann mit einem regulären Ausdruck wie ersetzt "([0-9])\\.([0-9])" with "\\1\\2", die zwar immer noch ein bisschen wie ein Hack, wäre weniger zerbrechlich als Replace(".","")

+3

Dies scheint eine Menge Overhead, wenn er beide Enden der Konvertierung steuert, die es scheint, wie er es tut. – codekaizen

+0

Wie ich in der Frage gesagt habe, kann ich mir des Formats des Double sicher sein, da es eine existierende Extension-Methode gibt, die auf die nächste Hälfte gerundet wird. Ich hatte auf eine sekundäre Erweiterungsmethode gehofft, die die Zeichenfolge zurückgibt. zB double.RoundToNearestHalf(). ToImageLink(). – RPM1984

+0

So sehr ich reguläre Ausdrücke mag (und ich auch), .NET kann damit besser umgehen. Dennoch ist etwas wie 'Regex.Replace (" 1.5 ", @" \ D "," ")" wahrscheinlich robuster, Ihre Regex macht spezifische Annahmen bezüglich des Formats der Zeichenkette. – Kobi

1

einen hashtable/Wörterbuch verwenden und Zuordnungen halten von doppelt, um dort zu string.Das wird viel robuster und einfacher als das Parsen Ihrem Doppel

+0

Was ist der Unterschied zwischen diesem und einem hartcodierten Schalter/wenn sonst noch eine Aussage? Der einzige Unterschied besteht in der Möglichkeit, eine Suche durchzuführen, aber der eigentliche Code, der noch hart codiert werden muss (zB items.Add (0.5, "05")) – RPM1984

+0

Eine Hashtabelle könnte die Leistung möglicherweise erhöhen, wenn Sie mit größeren Nachschlagetabellen arbeiten , aber für eine so kleine Liste wie Ihr Beispiel wäre es besser, wenn Sie eine riesige switch-Anweisung verwenden würden. – drharris

+0

Stimmt, und wenn es einen direkten einfachen Weg gibt, dann sollten wir kein Wörterbuch benutzen. Wenn ich jedoch eine String-Manipulationslogik parsen und setzen müsste, würde ich das einfach vermeiden, weil das fehleranfällig ist. –

4

Wenn Sie mit Zeichenketten wie 00, 05, 10, 15, 20 ... leben könnten usw., könnten Sie einfach verwenden

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

Wenn in allen Ländern InvariantCulture als Argument ToString, um die Verwendung eines Dezimalpunktes zu zwingen (" ") verwendet, nicht (in Deutschland würde der Standard sein"," zum Beispiel):

rating.ToString(CultureInfo.InvariantCulture).Replace(".",""); 
+0

'Replace (". "," ")' Scheint wie der beste Weg. – Kobi

-1

Do not Versuchen Sie, eine einfachere Antwort auf etwas zu finden, das bereits einfach ist. Der einfachste Weg, es zu tun ist, diesen Code zu verwenden:

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

Wenn es etwas, das Sie werden viel zu tun, wickeln Sie es in einer Funktion:

string ConvertToString(double dblNumber) 
{ 
    return dblNumber.ToString("N1").Replace(".","").Trim('0'); 
} 
+0

Ich dachte über 'TrimEnd', aber bedenke, dass es' 0' in '" "verwandelt. 'Trim' dreht auch' 05' auf '5', was falsch ist. – Kobi

+0

Der 'Trim ('0')' Teil ist falsch. Es könnte niemals eine "0" -Ausgabe geben ... – MartinStettner

2

Sie nur Replace(".", string.Empty); verwenden können ohne die Notwendigkeit für Replace(".0", string.Empty)

Überprüfung der Code unten

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)); 
      } 

das Ergebnis wird alt text http://img689.imageshack.us/img689/6591/doubletostring.jpg

+0

+1, um sich die Zeit zu nehmen, Ihre Antwort auszuprobieren und den Beweis dafür zu erbringen, dass es funktioniert. – RPM1984

1

mit Dezimalformate Unordnung zu vermeiden, ich das ganze Teil als eine ganze Zahl formatiert werden würde und ein Array-Lookup für den Bruchteil verwenden:

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" }; 
Verwandte Themen