Domanda

Se eseguo la seguente dichiarazione:

string.Compare("mun", "mün", true, CultureInfo.InvariantCulture)

Il risultato è '-1', indicando che 'mun' ha un valore numerico inferiore 'Mün'.

Tuttavia, se eseguo questa dichiarazione:

string.Compare("Muntelier, Schweiz", "München, Deutschland", true, CultureInfo.InvariantCulture)

I get '1', indicando che 'Muntelier, Schewiz' dovrebbe andare scorso.

Si tratta di un bug nel confronto? O, più probabilmente, c'è una regola dovrei prendere in considerazione durante l'ordinamento stringhe contenenti accentato


Il motivo per cui questo è un problema è, sto ordinamento di un elenco e poi fare un filtro binario manuale che è destinata ad ottenere ogni stringa che inizia con 'xxx'.

In precedenza stavo usando il metodo 'Dove' LINQ, ma ora devo usare questa funzione personalizzata scritta da un'altra persona, perché dice che funziona meglio.

Ma la funzione personalizzata non sembra prendere in considerazione qualunque regole 'unicode' NET ha. Quindi, se gli dico di filtrare per 'Mün', non trova nessun articolo, anche se ci sono voci nell'elenco che iniziano con 'mun'.

Questo sembra essere a causa del l'ordinamento incoerente di caratteri accentati, a seconda di quali caratteri andare dopo il carattere accentato.


OK, credo di aver risolto il problema.

Prima del filtro, faccio una specie sulla base del primo n lettere di ogni stringa, dove n è la lunghezza della stringa di ricerca.

È stato utile?

Soluzione

C'è un algoritmo di spareggio sul posto di lavoro, vedi http://unicode.org/reports/tr10/

  

Per affrontare la complessità della   sensibile alla lingua ordinamento, un   algoritmo di confronto multilivello   impiegato. Nel confronto tra due parole, per   ad esempio, la caratteristica più importante è   il carattere di base: come la   differenza tra una A e una B.   differenze di accento sono in genere   ignorata, se ci sono delle differenze   le lettere di base. differenze caso   (Maiuscolo contro minuscolo), sono   tipicamente ignorata, se ce ne sono   differenze nella base o accenti.   La punteggiatura è variabile. In qualche   situazioni un carattere di punteggiatura è   trattata come un carattere di base. Nel   altre situazioni, si dovrebbe essere ignorato   se ci sono qualsiasi base, accento, o caso   differenze. Ci può essere anche un   finale, tie-breaking livello, per cui se   non ci sono altre differenze a tutti   nella stringa, il codice (normalizzata)   ordine punto viene utilizzato.

Quindi, "Munt ..." e "... Munc" sono in ordine alfabetico diverso e basato sul tipo "t" e "c".

considerando che, "mun" e "Mün" sono in ordine alfabetico lo stesso ( "u" equivelent a "ü" in lingue perdute) in modo che i codici di caratteri vengono confrontati

Altri suggerimenti

Sembra che il carattere accentato è utilizzato solo in una sorta di situazione di "tie-break" - in altre parole, se le stringhe sono uguali altrimenti

.

Ecco alcuni esempi di codice per dimostrare:

using System;
using System.Globalization;

class Test
{
    static void Main()
    {
        Compare("mun", "mün");
        Compare("muna", "münb");
        Compare("munb", "müna");
    }

    static void Compare(string x, string y)
    {
        int result = string.Compare(x, y, true, 
                                   CultureInfo.InvariantCulture));

        Console.WriteLine("{0}; {1}; {2}", x, y, result);
    }
}

(Ho provato ad aggiungere uno spazio dopo la "n", così, per vedere se è stato fatto su confini di parola -. Non lo è)

Risultati:

mun; mün; -1
muna; münb; -1
munb; müna; 1

Ho il sospetto che questo sia corretto da varie regole complicate Unicode - ma non so abbastanza su di loro

.

Per quanto riguarda se è necessario tener conto di questo ... non mi aspetto così. Che cosa stai facendo che è gettato da questo?

A quanto ho capito questo, è ancora un po 'coerente. Quando si confrontano utilizzando CultureInfo.InvariantCulture il carattere ü dieresi viene trattato come il u non accentato carattere.

Come le corde nel primo esempio, ovviamente, non sono uguali il risultato non sarà 0 ma -1 (che sembra essere un valore di default). Nel secondo esempio, Muntelier va ultimo perché t segue c in alfabeto.

non ho potuto trovare alcuna documentazione chiara in MSDN che spiega queste regole, ma ho scoperto che

string.Compare("mun", "mün", CultureInfo.InvariantCulture,  
    CompareOptions.StringSort);

e

string.Compare("Muntelier, Schweiz", "München, Deutschland", 
    CultureInfo.InvariantCulture, CompareOptions.StringSort);

dà il risultato desiderato.

In ogni caso, penso che sarebbe meglio basare la vostra ordinamento su una cultura specifica, come la cultura dell'utente corrente (se possibile).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top