Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

205
Vistas
Orden predeterminado en C# frente a F#

Considere los dos fragmentos de código que simplemente ordenan cadenas en C# y F# respectivamente:

C#:

 var strings = new[] { "Tea and Coffee", "Telephone", "TV" }; var orderedStrings = strings.OrderBy(s => s).ToArray();

F#:

 let strings = [| "Tea and Coffee"; "Telephone"; "TV" |] let orderedStrings = strings |> Seq.sortBy (fun s -> s) |> Seq.toArray

Estos dos fragmentos de código devuelven resultados diferentes:

  • C#: té y café, teléfono, TV
  • F#: TV, té y café, teléfono

En mi caso específico, necesito correlacionar la lógica de orden entre estos dos idiomas (uno es el código de producción y el otro es parte de una afirmación de prueba). Esto plantea algunas preguntas:

  • ¿Existe una razón subyacente para las diferencias en la lógica de ordenación?
  • ¿Cuál es la forma recomendada de superar este "problema" en mi situación?
  • ¿Este fenómeno es específico de las cadenas o también se aplica a otros tipos de .NET?

EDITAR

En respuesta a varios comentarios de sondeo, la ejecución de los fragmentos a continuación revela más sobre la naturaleza exacta de las diferencias de este orden:

F#:

 let strings = [| "UV"; "Uv"; "uV"; "uv"; "Tv"; "TV"; "tv"; "tV" |] let orderedStrings = strings |> Seq.sortBy (fun s -> s) |> Seq.toArray

C#:

 var strings = new[] { "UV", "Uv", "uv", "uV", "TV", "tV", "Tv", "tv" }; var orderedStrings = strings.OrderBy(s => s).ToArray();

Da:

  • C#: televisión, televisión, televisión, televisión, ultravioleta, ultravioleta, ultravioleta, ultravioleta
  • F#: TV, TV, UV, UV, TV, TV, UV, UV

El orden lexicográfico de las cadenas difiere debido a una diferencia en el orden subyacente de los caracteres:

  • C#: "aAbBcCdD...tTuUvV..."
  • F#: "ABC..TUV..Zabc..tuv.."
over 4 years ago · Santiago Trujillo
3 Respuestas
Responde la pregunta

0

Diferentes bibliotecas hacen diferentes elecciones de la operación de comparación predeterminada en cadenas. F# tiene un valor predeterminado estricto para distinguir entre mayúsculas y minúsculas, mientras que LINQ to Objects no distingue entre mayúsculas y minúsculas.

Tanto List.sortWith como Array.sortWith permiten especificar la comparación. Al igual que una sobrecarga de Enumerable.OrderBy .

Sin embargo, el módulo Seq no parece tener un equivalente (y no se agrega uno en 4.6).

Para las preguntas específicas:

¿Existe una razón subyacente para las diferencias en la lógica de ordenación?

Ambos pedidos son válidos. En los casos ingleses la insensibilidad parece más natural, porque es a lo que estamos acostumbrados. Pero esto no lo hace más correcto.

¿Cuál es la forma recomendada de superar este "problema" en mi situación?

Sea explícito sobre el tipo de comparación.

¿Este fenómeno es específico de las cadenas o también se aplica a otros tipos de .NET?

char también se verá afectado. Y cualquier otro tipo donde haya más de un ordenamiento posible (ej. un tipo People : podrías ordenar por nombre o fecha de nacimiento dependiendo de los requerimientos específicos).

over 4 years ago · Santiago Trujillo Denunciar

0

Consulte la sección 8.15.6 de las especificaciones de idioma .

Las cadenas, las matrices y los enteros nativos tienen una semántica de comparación especial, todo lo demás simplemente va a IComparable si se implementa (modulo varias optimizaciones que producen el mismo resultado).

En particular, las cadenas de F# usan la comparación ordinal de forma predeterminada, a diferencia de la mayoría de .NET, que usa la comparación con reconocimiento cultural de forma predeterminada.

Obviamente, esta es una incompatibilidad confusa entre F # y otros lenguajes .NET, sin embargo, tiene algunos beneficios:

  • compatibilidad con OCAML
  • Las comparaciones de cadenas y caracteres son consistentes
    • C# Comparer<string>.Default.Compare("a", "A") // -1
    • C# Comparer<char>.Default.Compare('a', 'A') // 32
    • F# compare "a" "A" // 1
    • F# compare 'a' 'A' // 32

Editar:

Tenga en cuenta que es engañoso (aunque no incorrecto) afirmar que "F# usa una comparación de cadenas que distingue entre mayúsculas y minúsculas ". F# usa la comparación ordinal , que es más estricta que solo distingue entre mayúsculas y minúsculas.

 // case-sensitive comparison StringComparer.InvariantCulture.Compare("[", "A") // -1 StringComparer.InvariantCulture.Compare("[", "a") // -1 // ordinal comparison // (recall, '[' lands between upper- and lower-case chars in the ASCII table) compare "[" "A" // 26 compare "[" "a" // -6
over 4 years ago · Santiago Trujillo Denunciar

0

Esto no tiene nada que ver con C# vs F#, o incluso con IComparable , sino que solo se debe a las diferentes implementaciones de clasificación en las bibliotecas.

El TL;DR; versión es que ordenar cadenas puede dar diferentes resultados:

 "tv" < "TV" // false "tv".CompareTo("TV") // -1 => implies "tv" *is* smaller than "TV"

O aún más claro:

 "a" < "A" // false "a".CompareTo("A") // -1 => implies "a" is smaller than "A"

Esto se debe a que CompareTo usa la referencia cultural actual (consulte MSDN) .

Podemos ver cómo se desarrolla esto en la práctica con algunos ejemplos diferentes.

Si usamos la ordenación estándar de F#, obtenemos el resultado de mayúsculas primero:

 let strings = [ "UV"; "Uv"; "uV"; "uv"; "Tv"; "TV"; "tv"; "tV" ] strings |> List.sort // ["TV"; "Tv"; "UV"; "Uv"; "tV"; "tv"; "uV"; "uv"]

Incluso si lanzamos a IComparable obtenemos el mismo resultado:

 strings |> Seq.cast<IComparable> |> Seq.sort |> Seq.toList // ["TV"; "Tv"; "UV"; "Uv"; "tV"; "tv"; "uV"; "uv"]

Por otro lado, si usamos Linq de F#, obtenemos el mismo resultado que el código de C#:

 open System.Linq strings.OrderBy(fun s -> s).ToArray() // [|"tv"; "tV"; "Tv"; "TV"; "uv"; "uV"; "Uv"; "UV"|]

Según MSDN , el método OrderBy "compara claves usando el comparador predeterminado Default".

Las bibliotecas de F# no usan Comparer de forma predeterminada, pero podemos usar sortWith :

 open System.Collections.Generic let comparer = Comparer<string>.Default

Ahora, cuando hacemos este tipo, obtenemos el mismo resultado que LINQ OrderBy :

 strings |> List.sortWith (fun xy -> comparer.Compare(x,y)) // ["tv"; "tV"; "Tv"; "TV"; "uv"; "uV"; "Uv"; "UV"]

Alternativamente, podemos usar la función incorporada CompareTo , que da el mismo resultado:

 strings |> List.sortWith (fun xy -> x.CompareTo(y)) // ["tv"; "tV"; "Tv"; "TV"; "uv"; "uV"; "Uv"; "UV"]

Moraleja del cuento: si le importa clasificar, ¡siempre especifique la comparación específica que usará!

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda