2012-04-02 10 views
7

È possibile prelevare un valore casuale da una struttura di tipo array recuperando un indice casuale.Come si recupera un oggetto casuale da un'istanza NSSet?

Come posso prelevare un valore casuale da un oggetto NSSet che memorizza oggetti NSNumber? Non sono riuscito a trovare un metodo di istanza di NSSet che recuperi un valore casuale.

+2

uso '[MySet allObjects]' che restituirà un array e quindi usa la tua logica esistente per ottenere un indice casuale –

+0

bbum preso da un grosso errore che ho fatto nella mia risposta, grazie. Eliminata. – Almo

+1

Vuoi casuale, o semplicemente non ti interessa quale? Specificamente, voglio dire, "Sei a conoscenza di' - [NSSet anyObject] '?" –

risposta

5

In breve, non è possibile recuperare direttamente un oggetto casuale da un NSSet.

Hai bisogno di trasformare il set in un array - in qualcosa che ha un indice che può essere randomizzato - re-architecting il tuo codice per usare un array o potresti implementarlo usando questo bit di pseudo-codice :

randomIndex = ...random-generator....(0 .. [set count]); 
__block currentIndex = 0; 
__block selectedObj = nil; 
[set enumerateObjectsWithOptions:^(id obj, BOOL *stop) { 
    if (randomIndex == currentIndex) { selectedObj = obj; *stop = YES } 
    else currentIndex++; 
}]; 
return selectedObj; 

Sì, itera l'insieme, potenzialmente l'intero set, quando si afferra l'oggetto. Tuttavia, l'iterazione è praticamente ciò che accadrà nella conversione ad un NSArray comunque. Finché il set non è così grande e non lo chiami quello spesso, nessun grosso problema.

+0

L'idea generale qui è corretta, tuttavia avevo bisogno di modificarlo e implementare lo pseudo-codice per compilare . Ecco la mia versione: https://gist.github.com/4392708 – Eliot

4

Anche se mi piace, la risposta @bbum verrà interrotta presto in alcune occasioni a causa dell'uso di stop nel blocco di enumerazione.

Per facilitare la lettura e la facilità di ricordare ciò che sta succedendo quando si rivisitare questo codice in futuro vorrei andare con il suo primo consiglio di turn the set into an array

NSInteger randomIndex = ..random-generator....(0 .. [set count]) 
id obj = [set count] > 0 ? [[set allObjects] objectAtIndex:randomIndex] : nil; 
Problemi correlati