Od Swift 1.2 (dostępny jako wersja beta) Apple wprowadza typ kolekcji Set
.Jak uzyskać losowy element z zestawu w Swift?
Say, Mam zestaw jak:
var set = Set<Int>(arrayLiteral: 1, 2, 3, 4, 5)
Teraz chcę dostać losowy element z niego. Pytanie brzmi: jak? Set
nie udostępnia subscript(Int)
, jak Array
. Zamiast tego ma subscript(SetIndex<T>)
. Ale po pierwsze, SetIndex<T>
nie ma dostępnych inicjalizatorów (stąd nie mogę po prostu utworzyć indeksu z potrzebnym offsetem), a po drugie, nawet jeśli mogę uzyskać indeks dla pierwszego elementu w zbiorze (var startIndex = set.startIndex
), to jedyny sposób może dostać się do N-tego indeksu przez kolejne połączenia do successor()
.
Zatem można zobaczyć tylko dwie możliwości w tym momencie, zarówno brzydkie i kosztownych:
- Konwersja zestawu do tablicy (
var array = [Int](set)
) i dokonuje indeksu dolnego (który idealnie przyjmujeInt
); lub - Pobierz indeks pierwszego elementu w zbiorze, przechodź przez łańcuchy metod
successor()
, aby uzyskać indeks N-ty, a następnie odczytaj odpowiedni element za pomocą indeksu zestawu.
Czy tęsknię za jakimś innym sposobem?
UPDATE
Jak @rintaro wskazał, należy użyć wcześniej() funkcja natychmiast dostać się do indeksu chcę. Np .:
var set = Set<Int>(arrayLiteral: 1, 2, 3, 4, 5)
let randomOffset = Int(arc4random_uniform(UInt32(set.count)))
let random = set[advance(set.startIndex, randomOffset)]
UPDATE 2
Okazuje się, że advance()
ma złożoność O (n), co zasadniczo czyni ją równoważne prostu przechodząc przez łańcuch successor()
.
Dzięki @rintaro! Właśnie tego szukałem. – courteouselk