2010-07-26 10 views
11

Tratando de no repetirme (estar seco) aquí, ayúdame. =)¿Cómo convertir de manera inteligente y segura un doble a cadena?

Tengo un doble que representa una calificación/5.

Los valores posibles son:

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

quiero convertir esto en una cadenasin el punto decimal.

Así que los valores se convertiría en:

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

Por qué estoy haciendo esto? Porque yo estoy tratando de crear dinámicamente un vínculo basado en el valor:

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

Los valores posibles son manejados/validado en otros lugares, en otras palabras, puedo estar 100% seguro de que el valor será siempre uno de los que he mencionado .

¿Alguna idea? ¿Algún formato especial que puedo usar en el método .ToString()? ¿O estoy atrapado con una declaración de cambio no DRY? ¿O puedo descaradamente hacer un decimal.ToString().Replace(".","")?

EDIT:

Whoah, gracias por todas las respuestas a los chicos! =)

La mayoría de las respuestas son correctas, así que lo dejaré abierto durante aproximadamente un día y elegiré la respuesta con la mayor cantidad de votos.

De todos modos, terminé creando un simple método de extensión:

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

supongo que era un caso de "Kiss" y "seco". En este caso, el azúcar sintáctico de los métodos de extensión lo mantuvo SECO, y la implementación de una sola línea satisface a KISS.

+0

He intentado crear un 'NumberFormatInfo', pero get 'Decimal separator no puede ser la cadena vacía'. Vergüenza. – Kobi

+1

+1 para hacer una pregunta bien estructurada – hydrogen

Respuesta

9

delimitador decimal depende de las preferencias actuales de cultivo:

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

reemplazará '.' o ',' con ""

+1

Probablemente sea más fácil usar CultureInfo al convertir el número a cadena, como lo sugieren otras respuestas. Entonces * sabes * el formato de cadena, y puedes simplemente reemplazar el punto. – Kobi

+0

@Kobi: Sí, cuando lo sepa y esté absolutamente seguro de que el delimitador es punto, no coma.El delimitador dinámico es muy fácil de usar, minimiza las cadenas de código duro y muy inteligente, ya que OP preguntó – abatishchev

2

Me limitaré a utilizar el método "descarado" que describes al final. En la semántica pura de la cosa, estás manipulando una cadena, no el número real, así que creo que un reemplazo de cadena sería exactamente la receta correcta aquí.

Si realmente quiere complicarlo, considere crear un nuevo IFormatProvider para esta situación. Esta sería una mejor forma de detectar posibles errores, pero agrega una capa de complejidad.

0

Se podría llamar ToString(), y luego usar una expresión regular como el reemplazo de "([0-9])\\.([0-9])" with "\\1\\2", que, aunque todavía un poco de un truco, sería menos frágil que Replace(".","")

+3

Esto parece un exceso de sobrecarga si controla ambos extremos de la conversión, lo cual parece que lo hace. – codekaizen

+0

Como dije en la pregunta, puedo estar seguro del formato del doble, ya que hay un método de extensión existente que redondea a la mitad más cercana. Esperaba un método de extensión secundario que devuelva la cadena. es decir double.RoundToNearestHalf(). ToImageLink(). – RPM1984

+0

Tanto como me gustan las expresiones regulares (y lo hago), .net puede manejarlo mejor. Sin embargo, algo como 'Regex.Replace (" 1.5 ", @" \ D "," ")' es probablemente más robusto, su expresión regular hace suposiciones específicas en cuanto al formato de la cadena. – Kobi

1

Use una tabla hash/diccionario y mantener las asignaciones de doble para encadenar allí.Eso será mucho más robusto y más simple que analizar su doble

+0

¿Cuál es la diferencia entre eso y una instrucción de cambio de código/if else? La única diferencia es poder hacer una búsqueda, pero el código real que aún necesita ser codificado (es decir, items.Add (0.5, "05")) – RPM1984

+0

Una tabla hash puede potencialmente aumentar el rendimiento si se trata de tablas de búsqueda más grandes , pero por una lista tan pequeña como tu ejemplo, estarías mejor con una declaración de cambio gigante. – drharris

+0

Es cierto, y si hay una forma directa y sencilla de hacerlo, entonces seguro que no deberíamos usar un diccionario. Sin embargo, si tuviera que analizar y poner algo de lógica de manipulación de cadenas, lo evitaría simplemente porque es propenso a errores. –

4

Si pudiera vivir con cadenas como 00, 05, 10, 15, 20 ... etc., simplemente podría usar

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

Si No, utilizar InvariantCulture como argumento para ToString con el fin de forzar el uso de un punto decimal (" ') en todos los países (en Alemania el valor por defecto será'," por ejemplo):

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

'Reemplazar (". "," ")' Parece la mejor manera. – Kobi

-1

no hacer intenta encontrar una respuesta más simple a algo que ya es simple. La forma más sencilla de hacerlo es utilizar este código:

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

Si es algo que va a estar haciendo un montón, lo envuelve en una función:

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

Pensé en 'TrimEnd', pero tenga en cuenta que convierte' 0' en '" "'. 'Trim' también convierte' 05' en '5', lo cual es incorrecto. – Kobi

+0

La parte 'Trim ('0')' es incorrecta. Nunca podría haber una salida "0" ... – MartinStettner

2

sólo puede utilizar Replace(".", string.Empty); sin necesidad de Replace(".0", string.Empty)

cheque el código de abajo

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

el resultado será alt text http://img689.imageshack.us/img689/6591/doubletostring.jpg

+0

+1 por tomarse el tiempo para probar su respuesta y mostrar la prueba de que funciona. – RPM1984

1

Para evitar ensuciar con formatos decimales, que define el formato de la parte entera como un entero y utilizar una búsqueda de matriz para la parte fraccionaria:

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" }; 
Cuestiones relacionadas