Come posso ottenere in modo elegante un numero specifico (> 1) di elementi casuali distinti da una raccolta?Come ottenere un numero specifico di elementi casuali da una raccolta in Smalltalk?
risposta
Questa è una cosa che penso sguardi più o meno bello, ma non è così efficiente come può essere:
yourCollection asSet asOrderedCollection shuffled first: numberOfElements
Si consideri il seguente frammento di codice
sample: anInteger from: aCollection using: aGenerator
| sample |
sample := Set new: anInteger.
[sample size = anInteger]
whileFalse: [ | element |
element := aCollection atRandom: aGenerator.
sample add: element].
^sample asArray
Alcune osservazioni
Generatore esplicito: utilizza esplicitamente un determinato generatore, ad esempio un'istanza di
Random
, che ho chiamatoaGenerator
. Per motivi matematici, se stai ricevendo campioni per la tua applicazione, tutti dovrebbero usare lo stesso generatore per tutto il tuo programma. Anche questo ti darà un ulteriore vantaggio: salva e successivamente ripristina ilseed
e sarai in grado di riprodurre un precedente comportamento "casuale" del tuo sistema, che è buono per il test.Nessun controllo la disponibilità: il codice non verifica che è possibile ottenere il campione desiderato, che sarebbe il caso se
aCollection
non hai almenoanInteger
elementi diversi.Codice classe: il metodo dovrebbe passare a una classe.
Ad esempio:
Random >> sample: anInteger from: aCollection
| sample |
sample := Set new: anInteger.
[sample size = anInteger]
whileFalse: [ | element |
element := aCollection atRandom: self.
sample add: element].
^sample asArray
UPDATE
Ecco un altro approccio:
Random >> remove: anInteger from: aCollection
| sample |
sample := OrderedCollection new: anInteger.
anInteger timesRepeat: [| index element |
index := aCollection size atRandom: self.
element := aCollection removeAt: index.
sample add: element].
^sample
commento
Di solito succede che quando vogliamo campionare senza ripetizione, vogliamo anche rimuovere gli elementi dalla collezione mentre li selezioniamo casualmente. In questi casi, ciò che spesso accade è che la collezione è nota per non avere ripetizioni.
Hmm, mi piace l'approccio "generatore di byo", ma se la raccolta e la dimensione del campione sono grandi, potresti rimanere bloccato fino alla fine, aspettando un po 'che il generatore scelga un numero "libero". –
@ AmosM.Carpenter buon punto. Quello che uso è più vicino al secondo approccio. –
Mi spiace essere nitpicky, ma non dovresti usare '#removeIndex:' - è pensato per essere privato. L'uso del metodo pubblico '#removeAt:' invece avrebbe il vantaggio aggiuntivo di rispondere all'elemento rimosso, il che significa che è possibile eliminare la variabile temporanea extra 'element' (ad esempio, basta aggiungere" esempio: (aCollection removeAt: index) ') .Entrambi i metodi "remove" si trovano su "OrderedCollection", quindi non funzionerà con altri tipi di collezioni. –
- 1. Come ottenere elementi casuali da un array
- 2. Ottenere un oggetto specifico da una raccolta in Jekyll
- 3. Come ottenere elementi casuali da un set in Swift?
- 4. Come ottenere un numero specifico in un python dell'array
- 5. Ottieni elementi casuali da hashset?
- 6. Come ottenere il numero di elementi in ObservableCollection da XAML?
- 7. Come ottenere il numero di elementi in una struttura?
- 8. BackboneJS: carica più elementi in una raccolta
- 9. Recupera x elementi casuali da un array
- 10. Come ottenere il numero di elementi in una casella combinata?
- 11. Come ottenere i valori casuali da array in C#
- 12. Organizzazione di elementi di raccolta in una griglia
- 13. Ottenere 3 record casuali da una tabella
- 14. Da stringa a intero Smalltalk
- 15. Raccogliere più elementi casuali da una lista in Java
- 16. Come scegliere 2 elementi casuali da un set Python?
- 17. jQuery Ottieni elementi casuali da una selezione Restituito da $ (selettore)
- 18. Come estrarre un intervallo da una raccolta in PowerShell?
- 19. Come leggere un numero specifico di byte da uno stream?
- 20. Come creare una raccolta parallela Scala da una raccolta Java
- 21. Come ottenere risultati casuali da Microsoft Z3?
- 22. Ottenere valori casuali da un array
- 23. Ottenere un numero specifico di risultati da una query XPath XmlDocument
- 24. Come ottenere l'origine di elementi ordinati da un datagrid
- 25. Prendere n elementi casuali da un elenco <E>?
- 26. Come inserire un oggetto (tipo di oggetto Modello) in oggetto di raccolta in Laravel con un numero di indice specifico?
- 27. Come posso contare gli elementi in una matrice che hanno un valore di attributo specifico?
- 28. Riempimento per ottenere un numero specifico di cifre in un numero
- 29. Dividere un numero in parti disuguali casuali
- 30. Ottenere numeri casuali da una lista di interi
Molto elegante. L'unico modo che potevo vedere per migliorare l'efficienza (che in genere non sarebbe un problema, ma alcune persone ne restano appese ...) sarebbe di mescolare gli _indices_ invece della raccolta (perché ci sarebbero meno indici) , e poi usa qualcosa come "#atAll:" per scegliere quegli indici randomizzati da un set (avresti ancora bisogno di # # asSet se li vuoi _distinct_). –