¿Hay una manera fácil en C # de crear ordinales para un número? Por ejemplo:
- 1 vuelve primero
- 2 regresa 2do
- 3 vuelve tercero
- ... etc.
¿Se puede hacer esto String.Format()
o hay alguna función disponible para hacerlo?
Esta página le ofrece una lista completa de todas las reglas de formato numérico personalizado:
http://msdn.microsoft.com/en-us/library/0c899ak8.aspx
Como puede ver, no hay nada allí sobre ordinales, por lo que no se puede hacer usando String.Format. Sin embargo, no es realmente tan difícil escribir una función para hacerlo.
public static string AddOrdinal(int num)
{
if( num <= 0 ) return num.ToString();
switch(num % 100)
{
case 11:
case 12:
case 13:
return num + "th";
}
switch(num % 10)
{
case 1:
return num + "st";
case 2:
return num + "nd";
case 3:
return num + "rd";
default:
return num + "th";
}
}
Actualización: Técnicamente, los ordinales no existen para <= 0, por lo que he actualizado el código anterior. También eliminó los ToString()
métodos redundantes .
También tenga en cuenta que esto no está internacionalizado. No tengo idea de cómo se ven los ordinales en otros idiomas.
¡Recuerda la internacionalización!
Las soluciones aquí solo funcionan para inglés. Las cosas se vuelven mucho más complejas si necesita admitir otros idiomas.
Por ejemplo, en español "1st" se escribiría como "1.o", "1.a", "1.os" o "1.as" dependiendo de si lo que está contando es masculino, femenino o plural !
Entonces, si su software necesita admitir diferentes idiomas, intente evitar los ordinales.
fuente
Mi versión de la versión de Jesse de las versiones de Stu y Samjudson :)
Prueba unitaria incluida para mostrar que la respuesta aceptada es incorrecta cuando el número <1
fuente
Simple, limpio, rápido
O mejor aún, como método de extensión
Ahora solo puedes llamar
o incluso tan directo como
fuente
Tendrás que rodar el tuyo. Desde lo alto de mi cabeza:
Entonces puedes hacer
Editado para las excepciones del 11/12/13. Dije desde lo alto de mi cabeza :-)
Editado para 1011: otros ya lo han solucionado, solo quieren asegurarse de que otros no tomen esta versión incorrecta.
fuente
Más bien me gustaron los elementos de las soluciones de Stu y Samjudson y los trabajé juntos en lo que creo que es un combo utilizable:
fuente
Si bien aún no he evaluado esto, debería poder obtener un mejor rendimiento evitando todas las declaraciones de casos condicionales.
Esto es Java, pero un puerto a C # es trivial:
Tenga en cuenta que la reducción de condicionales y el uso de la búsqueda de matriz deberían acelerar el rendimiento si se generan muchos ordinales en un ciclo cerrado. Sin embargo, también reconozco que esto no es tan legible como la solución de declaración de caso.
fuente
Similar a la solución de Ryan, pero aún más básico, solo uso una matriz simple y uso el día para buscar el ordinal correcto:
No he tenido la necesidad, pero supongo que podría usar una matriz multidimensional si quisiera tener soporte para múltiples idiomas.
Por lo que puedo recordar de mis días de Uni, este método requiere un esfuerzo mínimo del servidor.
fuente
Yo uso esta clase de extensión:
fuente
Se solicitó la versión "menos redundante" de la respuesta de samjudson ...
fuente
public static
y cambiaría el nombre a un nombre más mnemónico (es decir, "OrdinalSuffix"). La persona que llama puede querer la parte del número en diferentes formatos (es decir, con comas).Si alguien busca un revestimiento: p
fuente
fuente
EDITAR : Como YM_Industries señala en el comentario, la respuesta de samjudson funciona para números superiores a 1000, el comentario de nickf parece haberse ido, y no puedo recordar cuál fue el problema que vi. Dejó esta respuesta aquí para los tiempos de comparación.
Muchos de estos no funcionan para números> 999, como nickf señaló en un comentario (EDITAR: ahora falta).
Aquí hay una versión basada en una versión modificada de la respuesta aceptada de samjudson que sí.
También la respuesta de Shahzad Qureshi usando la manipulación de cuerdas funciona bien, sin embargo, tiene una penalización de rendimiento. Para generar muchos de estos, un programa de ejemplo de LINQPad hace que la versión de cadena sea 6-7 veces más lenta que esta entera (aunque tendría que generar mucho para notar).
Ejemplo de LINQPad:
fuente
Basado en las otras respuestas:
fuente
FWIW, para MS-SQL, esta expresión hará el trabajo. Mantenga el primer WHEN (
WHEN num % 100 IN (11, 12, 13) THEN 'th'
) como el primero en la lista, ya que esto se basa en ser probado antes que los demás.Para Excel:
La expresión
(MOD(A1-11,100)>2)
es VERDADERO (1) para todos los números, excepto los que terminan en11,12,13
(FALSO = 0). Entonces2 * RIGHT(A1) * (MOD(A1-11,100)>2) +1)
termina como 1 para el 12/11/13, de lo contrario:1 evalúa a 3
2 a 5,
3 a 7
otros: 9
- y los 2 caracteres requeridos se seleccionan a
"thstndrdth"
partir de esa posición.Si realmente desea convertir eso directamente a SQL, esto funcionó para mí para un puñado de valores de prueba:
fuente
Esta es la implementación
dart
y puede modificarse según el idioma.fuente
Si bien hay muchas buenas respuestas aquí, supongo que hay espacio para otra, esta vez basada en la coincidencia de patrones, si no para otra cosa, al menos para una legibilidad discutible
¿Y qué hace que esta solución sea especial? nada más que el hecho de que estoy agregando algunas consideraciones de rendimiento para varias otras soluciones
francamente, dudo que el rendimiento realmente sea importante para este escenario en particular (que realmente necesita los ordinales de millones de números), pero al menos muestra algunas comparaciones a tener en cuenta ...
fuente
Otra línea, pero sin comparaciones al indexar solo el resultado de la expresión regular en una matriz.
La versión de PowerShell se puede acortar aún más:
fuente
Otro 1 trazador de líneas.
fuente
Aquí está la clase de extensión DateTime. Copiar, pegar y disfrutar
clase estática pública DateTimeExtensions {
Resultado:
9 de octubre de 2014
fuente
Otra alternativa que utilicé en base a todas las otras sugerencias, pero no requiere una carcasa especial:
fuente