Sei abbastanza vicino per capire come funziona tale rimescolamento .. Nel suo secondo caso
pupils.OrderBy(x => x.Age);
il Comparer<int>.Default
viene utilizzato (i soggetti sono ordinati in base al Age
, semplice).
Nel primo caso, Comparer<Guid>.Default
viene utilizzato.
Ora come funziona?.
Ogni volta che si esegue Guid.NewGuid()
(presumibilmente) viene prodotto un diverso/originale/non duplicato Guid
.Ora quando lo fai
var randomNumbers = Enumerable.Range(0, 100).OrderBy(x => Guid.NewGuid());
i numeri sono ordinati sulla base dei Guids generati.
Ora, quali sono i numeri di telefono?
Sono interi a 128 bit rappresentati in forma esadecimale. Poiché 2^128 è un numero così grande, le possibilità di generare due Guidi sono molto rare/quasi impossibili. Poiché Guids mostra una sorta di casualità, anche l'ordine sarà casuale.
Come vengono confrontati due Guidi per far rispettare l'ordine?
È possibile confermare in base a un esperimento banale. Fare:
var guids = Enumerable.Range(0, 10).Select((x, i) =>
{
Guid guid = Guid.NewGuid();
return new { Guid = guid, NumberRepresentation = new BigInteger(guid.ToByteArray()), OriginalIndex = i };
}).ToArray();
var guidsOrderedByTheirNumberRepresentation = guids.OrderBy(x => x.NumberRepresentation).ToArray();
var guidsOrderedAsString = guids.OrderBy(x => x.Guid.ToString()).ToArray();
var randomNumbers = Enumerable.Range(0, 10).OrderBy(x => guids[x].Guid).ToArray();
//print randomNumbers.SequenceEqual(guidsOrderedByTheirNumberRepresentation.Select(x => x.OriginalIndex)) => false
//print randomNumbers.SequenceEqual(guidsOrderedAsString.Select(x => x.OriginalIndex)) => true
Così Comparer<Guid>.Default
si basa sulla rappresentazione di stringa del GUID.
parte:
Si dovrebbe usare Fisher-Yates mischiare per la velocità. Può essere
public static IEnumerable<T> Shuffle<T>(this IList<T> lst)
{
Random rnd = new Random();
for (int i = lst.Count - 1; i >= 0; i--)
{
int j = rnd.Next(i + 1);
yield return lst[j];
lst[j] = lst[i];
}
}
O per concisione, potrebbe essere solo (che può essere ancora più veloce di approccio Guid)
public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> lst)
{
Random rnd = new Random();
return lst.OrderBy(x => rnd.Next());
}
Non capisco la tua domanda qui. Nell'esempio sopra, supponendo che l'età sia un int, 'query' conterrà l'elenco ordinato. Quindi, l'array iniziale non è ordinato o mescolato. – ryadavilli
Ho aggiornato il post. Sto parlando del primo esempio di codice. –
Prova Fisher-Yates mischiare nel codice vero però .. Più veloce .. – nawfal