Kể từ khi Swift 1.2 (có sẵn dưới dạng beta tại thời điểm này), Apple giới thiệu loại bộ sưu tập Set
.Cách lấy phần tử ngẫu nhiên từ một bộ trong Swift?
Nói, tôi có một bộ như:
var set = Set<Int>(arrayLiteral: 1, 2, 3, 4, 5)
Bây giờ tôi muốn có được một yếu tố ngẫu nhiên ra khỏi nó. Câu hỏi là như thế nào? Set
không cung cấp subscript(Int)
như Array
. Thay vào đó, nó có subscript(SetIndex<T>)
. Nhưng trước tiên, SetIndex<T>
không có bộ khởi tạo có thể truy cập (do đó, tôi không thể tạo chỉ mục với số liệu tôi cần) và thứ hai ngay cả khi tôi có thể lấy chỉ mục cho phần tử đầu tiên trong một tập hợp (var startIndex = set.startIndex
). có thể đến chỉ số thứ N thông qua các cuộc gọi liên tiếp đến successor()
.
Vì vậy, tôi có thể thấy chỉ có 2 lựa chọn vào lúc này, cả hai xấu xí và tốn kém:
- Chuyển đổi các thiết lập vào mảng (
var array = [Int](set)
) và sử dụng subscript của nó (mà hoàn toàn chấp nhậnInt
); hoặc - Nhận chỉ mục của phần tử đầu tiên trong một tập hợp, đi qua chuỗi các phương pháp
successor()
để đến chỉ mục thứ N và sau đó đọc phần tử tương ứng thông qua chỉ số của tập hợp.
Tôi có bỏ lỡ một số cách khác không?
CẬP NHẬT
Như @rintaro chỉ ra, tôi nên sử dụng trước() để ngay lập tức nhận được chỉ số tôi muốn. Ví dụ .:
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
Nó chỉ ra rằng advance()
có độ phức tạp O (N), trong đó chủ yếu làm cho nó trở thành tương đương với chỉ đơn giản là đi qua chuỗi successor()
.
Cảm ơn @rintaro! Điều này thật đúng với gì mà tôi đã tìm kiếm. – courteouselk