2012-06-28 7 views
11
scala> Random.shuffle((1 to 10).toSet) 
res10: scala.collection.immutable.Set[Int] = Set(5, 10, 1, 6, 9, 2, 7, 3, 8, 4) 

scala> Random.shuffle((1 to 10).toSet) 
res11: scala.collection.immutable.Set[Int] = Set(5, 10, 1, 6, 9, 2, 7, 3, 8, 4) 

scala> Random.shuffle((1 to 10).toSet) 
res12: scala.collection.immutable.Set[Int] = Set(5, 10, 1, 6, 9, 2, 7, 3, 8, 4) 

scala> Random.shuffle((1 to 10).toList) 
res13: List[Int] = List(3, 9, 8, 5, 7, 6, 10, 2, 1, 4) 

scala> Random.shuffle((1 to 10).toList) 
res14: List[Int] = List(5, 10, 2, 9, 4, 7, 8, 6, 1, 3) 

scala> Random.shuffle((1 to 10).toList) 
res15: List[Int] = List(5, 9, 10, 6, 8, 3, 4, 1, 7, 2) 

Così shuffle può gestire le liste bene, ma non le serie? I set non possono essere mischiati? Perché res10 == res11 == res12?Comportamento di shuffle su Set vs List utilizzando scala.util.Random

+0

Il tuo reclamo non riguarda il comportamento di Random, ma piuttosto il comportamento di Set. Il contratto Set non implica la conservazione dell'ordine, consentendo convenientemente ottimizzazioni come il backup del Set con una tabella hash, quindi chiamareSet è un invito a riordinare la tua raccolta. –

risposta

20

set di Scala non sono ordinate (proprio come quelli matematici). Sono iterabile, tuttavia, non si può fare affidamento su l'ordine che si otterrà le voci in. Molte implementazioni di insiemi itererà gli stessi elementi nello stesso ordine, cioè,

scala> Set(1, 2, 3, 4, 5).toList == Set(5, 4, 3, 2, 1).toList 
res0: Boolean = true 

che spiega la effetto che stai vedendo qui. Non si dovrebbe mai fare affidamento su questo, tuttavia, potrebbe esserci un'implementazione valida Set valida per la quale quanto sopra non regge.

+1

Uh ... ok. Accetto la tua spiegazione, anche se non penso che Random.shuffle stia rispettando la postcondizione qui. L'algoritmo shuffle deve fornire un ordine casuale indipendentemente dal contenitore sottostante. È molto facile fornire questo comportamento. Ad esempio: Random.shuffle ((da 1 a 10) .toSet) può chiamare internamente Random.shuffle ((da 1 a 10) .toSet.toList) per ottenere un ordinamento arbitrario, che può quindi essere mescolato. –

+7

È un po 'strano, e non sono sicuro del motivo per cui 'shuffle' è definito per qualsiasi' TraversableOnce' (invece di dire 'Seq'). Semplicemente non è possibile scrivere una versione di 'shuffle' per gli insiemi che fornirebbero un ordine casuale, poiché non ha senso parlare di qualsiasi tipo di ordine per gli insiemi. –

+2

Ho appena visto la modifica del tuo commento: sì, ma 'shuffle' restituisce una raccolta dello stesso tipo del suo input, e non appena rimetti l'elenco mescolato in un set sei bloccato nella stessa situazione. –

1

a caso è "rimescolamento" del set; non ha alcun effetto visibile poiché gli insiemi non hanno un ordine. Il REPL capita di stampare gli insiemi mescolati allo stesso modo ogni volta:

scala> Set(1,2,3,4,5) 
res29: scala.collection.immutable.Set[Int] = Set(5, 1, 2, 3, 4) 

scala> Set(5,4,3,2,1) 
res30: scala.collection.immutable.Set[Int] = Set(5, 1, 2, 3, 4) 

scala> util.Random.shuffle(res30) 
res31: scala.collection.immutable.Set[Int] = Set(5, 1, 2, 3, 4) 
+1

Sì, è praticamente la stessa cosa della risposta esistente di tre anni fa –

+0

Non sono d'accordo. La mia risposta non è la stessa ed è più chiara e più facile da capire per un principiante. Mi piacerebbe sentire l'opinione di @kr su quale risposta è più chiara. Il suo commento indica che l'altra risposta non era. – retrospectacus

+0

Dato che @kr era "Ultimo accesso 21 agosto 13 alle 22:13" non è probabile che lo riceverai. E poiché lo ha accettato, presumo abbia trovato chiaro dopo i commenti. –