lunes, 30 de noviembre de 2015

Cadenas de Caracteres y Manipulación de Texto en C# - Parte 3/5: Comparación de Cadenas de Caracteres

Índice

1. Introducción
2. Palabras Clave
3. Comparación de Valores en .NET
3.1 Comparación semántica
3.2 Comparación ordinal
3.3 Modos de comparación
3.4 Comparación de cadenas de caracteres
3.5 Comparación de cadenas de caracteres por orden
4. Compración Ordinal vs. Comparación Cultural de Cadenas de Caracteres
5. Comparación Semántica de Cadenas de Caracteres
6. Comparación Ordinal de cadenas d ecaracteres
7. Conclusiones
8. Literatura & Enlaces

1. Introducción

En esta tercera parte de la serie Manipulación de Texto y Cadenas de Caracteres en C#, se estudia los métodos de comparación de cadenas de caracteres: comparación semántica y comparación ordinal. Estos métodos de comparación son de inmensa utilidad a la hora de construir nuevos tipos de datos para nuestros proyectos de ingeniería de software, o usar los definidos en las bibliotecas nativas de .NET Framework o desarrolladas por terceros, las cuales requieran un granulado sistema de comparación e igualdad. En especial se estudian los siguientes temas esenciales: comparación cultural vs comparación ordinal, comparación semántica de cadenas de caracteres y comparación ordinal de cadenas de caracteres.

2. Palabras Clave

  • Cadenas de caracteres
  • Comparación
  • Comparación ordinal
  • Comparación semántica
  • Cultura
  • Igualdad

3. Comparación de Valores en .NET

En Microsoft .NET se distingue entre la comparación semántica y la comparación ordinal (Albahari, 2012).

3.1 Comparación semántica

La comparación semántica -también conocida como comparación de igualdad- se caracteriza por determinar o validar si dos instancias son a nivel semántico iguales, es decir, si sus valores tienen el mismo significado en un determinado contexto (Albahari, 2012).

3.2 Comparación ordinal

Por su parte, la comparación ordinal consiste en comparar dos instancias respecto al orden natural de su tipo de dato. En el caso de números enteros la comparación ordinal consiste en determinar cuál es menor -descendencia-, cuál es mayor -ascendencia- o si los valores iguales.

3.3 Modos de comparación

Hay que tener en cuenta que estos modos de comparación son totalmente independientes y ninguno de ellos es una subcategoría del otro. Esto se advierte en Albahari (2012) de la siguiente manera:
"It's legal, for instance, to have two unequal values in the same ordering position."
Esto quiere decir que dos valores distintos pueden ocupar un misma posición de orden. Se puede pensar en este caso en agrupaciones o jerarquías de valores, por ejemplo.

3.4 Comparación de cadenas de caracteres

Para la comparación de cadenas de caracteres, el cual es tema principal de esta serie de artículos, el programador puede usar las siguientes dos alternativas:
  • el operador == o 
  • el método static Equals de la clase String
Para comparaciones básicas basta con el uso del operador ==, pero para comparaciones más granulares o especializadas, es preferible recurrir a la última opción: el método Equals. Con esto último el programador puede especificar opciones para no distinguir entre minúsculas y mayúsculas; algo que no se puede lograr con el operador nativo ==.

En Albahari (2012) se hace la siguiente advertencia:
"Another difference is that == does not work reliably on strings if the variables are cast to the object type."
En resumen, el operador de igualdad, ==, no es apto para comparar cadenas de caracteres convertidas al tipo de dato base object.

3.5 Comparación de cadenas de caracteres por orden

En .NET Framework el desarrollador encontrará los métodos de instancia: 
  • CompareTo
  • Compare, y 
  • CompareOrdinal
para efectuar una comparación ordinal entre instancias. Estos métodos se caracterizan por su tipo de retorno: que consiste en un número entero que determina su posición en una jerarquía de orden -ascendente o descendente-.

4. Comparación Ordinal vs. Comparación Cultural de Cadenas de Caracteres

.NET Framework cuenta con dos algoritmos de comparación de cadenas de caracteres (Albahari, 2012)
  • Ordinal y  
  • Cultural-sensitivo
Estos dos algoritmos de comparación de cadenas de caracteres se diferencian en que el primero, el ordinal, lleva a cabo las comparaciones de forma numérica. Esta comparación considera el valor numérico asignado en el juego de caracteres Unicode; mientras que el segundo, cultural-sensitivo, las comparaciones se interpretan de acuerdo a un alfabeto de una cultura específica (Albahari, 2012)

Vale advertir que respecto al método de comparación cultural-sensitivo existen estas dos variantes:
  • cultura actual: basada en la configuración regional del sistema actual donde se ejecuta la aplicación, y 
  • cultura no-variante: basada en el sistema americano.
Con un ejemplo se puede ampliar estos conceptos; en particular para diferenciar los algoritmos de comparación de cadenas caracteres. El siguiente programa en código fuente C# compara a nivel ordinal las cadenas de caracteres chsarp, CSharp y FSharp:

Al ejecutar este programa se obtienen los siguientes resultados -http://ideone.com/I5uOxy-:


Comparación independiente de la cultura:
einstein
Einstein
Newton

Comparación ordinal:
Einstein
Newton
einstein

Nótese que los resultados de la comparación de las cadenas "Einstein""einstein" y "Newton" con el uso StringComparer.InvariantCulture sigue el orden alfabético primeros letras minúsculas (a-z) y luego mayúsculas (A-Z); mientras que al especificar StringComparer.Ordinal para la comparación ordinal, el orden está basado en A...Z, a...z.

5. Comparación Semántica de Cadenas de Caracteres

La comparación semántica o de igualdad de cadenas de caracteres se puede llevar a cabo con los métodos 

public static bool Equals(string a, string b, StringComparison comparisonType)




public bool Equals(string value, StringComparison comparisonType)


Estos métodos están definidos en la clase String. El parámetro común de ambos métodos, StringComparison, es una enumeración con los siguientes miembros ("StringComparison Enumeration", 2015):
Miembros de StringComparison
Tabla 1. Miembros de StringComparison ("StringComparison Enumeration", 2015).

Con estos miembros de esta enumeración se especifica el modo de comparación del contenido de cadenas de caracteres.

Ejemplo de uso:

Archivo C# ComparacionSemantica.cs [Enlace alternativo][Enlace alternativo]:

Los resultados de ejecución de este código son:


¿Iguales EINSTEIN y Einstein?: True

¿Iguales Ṻ y Ǖ?: False

¿Iguales Ṻ y Ǖ?: True


La primera evaluación -línea 9- compara los valores de las cadenas de caracteres "EINSTEIN" y "Einstein" sin considerar si son o no mayúsculas; lo que da como resultado true. En el caso de la comparación ¿Iguales Ṻ y Ǖ? -línea 12- con el operador == su resultado es false debido a que son dos cadenas distintas -dos valores Unicode distintos: \u1E7A y \u01D5-.



Para el caso de ejemplo final -línea 15-, el resultado es dependiente de la configuración local de la computadora donde ejecuta el assembly.

6. Comparación Ordinal de Cadenas de Caracteres

En la clase System.String se halla el método CompareTo que cuenta con las siguientes versiones sobrecargadas ("String.CompareTo", 2015):
Método sobrecargado CompareTo
Tabla 2. Método sobrecargado CompareTo ("String.CompareTo", 2015).
Con este método de instancia se determina si una cadena de precede, procede o mantiene la misma posición en un orden específico a otra cadena de caracteres. El valor entero retornado determina su orden:
  • En caso de ser menor que cero: la instancia actual precede a otra cadena de caracteres.
  • En caso de ser igual a cero: la instancia mantiene la misma posición de orden.
  • En caso de ser mayor que cero: la instancia procede a otra cadena de caracteres.
Por ejemplo:

string cadena1 = "ani\u00ADmal";
string cadena2 = "animal";

Console.WriteLine (cadena1.CompareTo(cadena2)); // 0

Existen, además, los métodos Compare y CompareOrdinal para otros tipos de comparación. (Estos tipos de comparación se explorarán en otros artículos o recetas C#.)

7. Conclusiones

Se ha estudiado los métodos de comparación de cadenas de caracteres: semántico y ordinal. La distinción conceptual y práctica de éstos dos permite al programador conocer el conjunto de elementos de programa disponibles en .NET Framework para la comparación del contenido y orden de cadenas de caracteres. Se demostró, además, que la comparación se puede efectuar con dependencia o independencia de la configuración regional del sistema de cómputo donde se ejecuta un determinado programa que compara cadenas de caracteres. El próximo artículo de esta serie explicará la construcción de cadenas de caracteres a partir de la clase StringBuilder; en especial la propiedad de mutabilidad.

8. Literatura & Enlaces

Albahari, J., Albahari, B. (2012). C# 5.0 in a Nutshell. United States: O'Reilly Media.
StringComparison Enumeration (System) (2015, noviembre 30). Recuperado desde: https://msdn.microsoft.com/en-us/library/system.stringcomparison(v=vs.110).aspx.
String.CompareTo Method (System) (2015, noviembre 30). Recuperado desde: https://msdn.microsoft.com/en-us/library/system.string.compareto(v=vs.110).aspx.


V

No hay comentarios:

Publicar un comentario

Envíe sus comentarios, dudas, sugerencias, críticas. Gracias.