Wie man zufälliges element aus einer Gruppe in Swift?
Als der Swift 1.2, Apple stellt Set
Sammlung geben.
Sagen, ich habe einen Satz wie:
var set = Set<Int>(arrayLiteral: 1, 2, 3, 4, 5)
Nun möchte ich, um ein zufälliges element aus ihm heraus. Frage ist, wie? Set
nicht subscript(Int)
wie Array
tut. Stattdessen hat er subscript(SetIndex<T>)
. Aber Erstens SetIndex<T>
nicht zugänglich Initialisierungen (daher kann ich nicht einfach nur einen index erstellen, mit dem offset, die ich brauche), und zweitens, selbst wenn ich den index für das erste element in einem set ( var startIndex = set.startIndex
), dann ist die einzige Möglichkeit, die ich bekommen kann, um den N-TEN index wird durch aufeinanderfolgende Aufrufe successor()
.
Daher sehe ich nur 2 Optionen im moment, beide hässlich und teuer:
- Konvertieren das set in array (
var array = [Int](set)
) und seine Tiefstellung (was vollkommen akzeptiertInt
); oder - Bekommen index des ersten Elements im set, Durchlaufen die Kette von
successor()
Methoden zum abrufen des N-TEN index und Lesen Sie dann entsprechende element mittels set ist Tiefgestellt.
Vermisse ich einige andere Möglichkeit?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Wahrscheinlich der beste Ansatz ist
advance
die Spaziergängesuccessor
für Sie:(EDIT: Heh; Sie bemerkt, dass Sie tatsächlich aktualisiert, die Frage zu dieser Antwort, bevor ich habe es auf meine Antwort... naja, immer noch eine gute Idee, und ich lernte auch etwas. :D)
Können Sie auch zu Fuß das eher, als das Indizes (das war mein Erster Gedanke, aber dann erinnerte ich mich an
advance
).advance()
im Fall von Set hat die Komplexität O(N). Also technisch ist es das gleiche wie das Durchlaufen der Kette vonsuccessor()
es sieht einfach viel präziser und Absicht-klar. Ich fragte, ähnliche Frage bei Apple-Entwickler-forum, und er bekam eine Aufmerksamkeit des Personals => vielleicht in einem zukünftigen release von Swift gäbe es bessere tools zu machen, was ich will. Für jetzt, ich werde wahrscheinlich bleiben mitadvance()
. Die Sätze, die ich verwende, sind nicht so groß.advancedBy(_:)
auf dem indexextension Set { func randomElement() -> Element { let n = Int(arc4random_uniform(UInt32(count))); let i = startIndex.advancedBy(n); return self[i];} }
advance
ist nicht mehr verfügbar. Ändern Sie Zeile 3 anlet i = s.startIndex.advancedBy(n)
Beginnend mit Swift 4.2, die Sie verwenden können,
randomElement
:In swift 3
Als pro Anmerkungen oben re Swift-updates, verwendet eine kleine änderung für eine Erweiterung zu Set:
Wenn Sie möchten, eine 'random' - element aus einem
Set
dann nutzen Sie:Get die 0. index oder 1.000.000 th index macht keinen Unterschied - Sie sind alle ein willkürliches Objekt.
Aber, wenn Sie möchten, dass wiederholte Aufrufe, um wieder eine wahrscheinlich verschiedene element jedes mal, dann
first
passen vielleicht nicht in Rechnung stellen.first
ist immer 50.