Angenommen, ich habe ein Array und möchte ein Element zufällig auswählen.
Was wäre der einfachste Weg, dies zu tun?
Der offensichtliche Weg wäre array[random index]
. Aber vielleicht gibt es so etwas wie Rubins array.sample
? Oder wenn nicht, könnte eine solche Methode mithilfe einer Erweiterung erstellt werden?
array[random number from 0 to length-1]
, aber ich kann nicht herausfinden, wie man schnell ein zufälliges int generiert. Ich würde es beim Stapelüberlauf fragen, wenn ich nicht blockiert wäre :) Ich wollte die Frage nicht mit halben Lösungen verschmutzen, wenn es vielleicht welche gibt so etwas wie Rubysarray.sample
Antworten:
Swift 4.2 und höher
Der neue empfohlene Ansatz ist eine im Erfassungsprotokoll integrierte Methode :
randomElement()
. Es wird eine Option zurückgegeben, um den leeren Fall zu vermeiden, gegen den ich zuvor angenommen habe.Wenn Sie das Array nicht erstellen und nicht garantiert sind, dass die Anzahl> 0 ist, sollten Sie Folgendes tun:
Swift 4.1 und niedriger
Um Ihre Frage zu beantworten, können Sie dies tun, um eine zufällige Array-Auswahl zu erreichen:
Die Castings sind hässlich, aber ich glaube, sie sind erforderlich, es sei denn, jemand anderes hat einen anderen Weg.
quelle
man arc4random
und stackoverflow.com/questions/10984974/…removeRandomElement()
Funktion implementiertrandomElement()
. Es würde modelliert werdenremoveFirst()
, aber ein Objekt an einem zufälligen Index entfernen.0..<array.count
(aus mehreren Gründen, vor allem, weil es für Slices nicht funktioniert und fehleranfällig ist). Sie können tunlet randomIndex = array.indices.randomElement()
, gefolgt vonlet randomElement = array.remove(at: randomIndex)
. Sie könnten es sogar inlinelet randomElement = array.remove(at: array.indices.randomElement())
.Nach dem, was Lucas gesagt hat, können Sie eine Erweiterung der Array-Klasse wie folgt erstellen:
Beispielsweise:
quelle
T
wurde in umbenanntElement
.guard
überprüfen, ob das Array leer ist, und dann zurückkehrennil
.arc4random
macht Leistungssteigerungen völlig unbedeutend. Ich habe die Antwort aktualisiert.Swift 4 Version:
quelle
startIndex != 0
In Swift 2.2 kann dies so verallgemeinert werden, dass wir:
Implementieren der statischen
random
Eigenschaft fürUnsignedIntegerType
s:Dann für
ClosedInterval
s mitUnsignedIntegerType
Grenzen:Dann (etwas komplizierter) für
ClosedInterval
s mitSignedIntegerType
Grenzen (unter Verwendung der weiter unten beschriebenen Hilfsmethoden):... wo
unsignedDistanceTo
,unsignedDistanceFromMin
undplusMinIntMax
Hilfsmethoden können wie folgt umgesetzt werden:Schließlich für alle Sammlungen, in denen
Index.Distance == Int
:... die ein wenig für ganze
Range
Zahlen optimiert werden kann :quelle
Sie können auch die integrierte Funktion random () von Swift für die Erweiterung verwenden:
quelle
Ein weiterer Vorschlag von Swift 3
quelle
Folgende andere antworten aber mit Swift 2 Unterstützung.
Swift 1.x.
Swift 2.x.
Z.B:
quelle
Eine alternative funktionale Implementierung mit Überprüfung auf leeres Array.
quelle
Hier ist eine Erweiterung für Arrays mit einer leeren Array-Prüfung für mehr Sicherheit:
Sie können es so einfach verwenden :
Wenn Sie ein Framework bevorzugen , das auch einige weitere praktische Funktionen bietet, lesen Sie HandySwift . Sie können es über Karthago zu Ihrem Projekt hinzufügen und dann genau wie im obigen Beispiel verwenden:
Zusätzlich enthält es eine Option, um mehrere zufällige Elemente gleichzeitig abzurufen :
quelle
Swift 3
GameKit importieren
quelle
Swift 3 - einfach einfach zu bedienen.
Array erstellen
Erstellen Sie eine zufällige Farbe
Stellen Sie diese Farbe auf Ihr Objekt ein
Hier ist ein Beispiel aus einem
SpriteKit
Projekt, das aSKLabelNode
mit einem Zufall aktualisiertString
:quelle
Wenn Sie in der Lage sein möchten, mehr als ein zufälliges Element ohne Duplikate aus Ihrem Array herauszuholen, bietet GameplayKit Folgendes:
Sie haben einige Möglichkeiten für die Zufälligkeit, siehe GKRandomSource :
quelle
Ich finde, dass die Verwendung von GKRandomSource.sharedRandom () von GameKit am besten für mich funktioniert.
oder Sie können das Objekt an dem ausgewählten Zufallsindex zurückgeben. Stellen Sie sicher, dass die Funktion zuerst einen String zurückgibt und dann den Index des Arrays zurückgibt.
Kurz und auf den Punkt.
quelle
Derzeit gibt es eine integrierte Methode
Collection
:Wenn Sie bis zu
n
zufällige Elemente aus einer Sammlung extrahieren möchten, können Sie eine Erweiterung wie die folgende hinzufügen:Und wenn Sie möchten, dass sie eindeutig sind, können Sie a verwenden
Set
, aber die Elemente der Sammlung müssen demHashable
Protokoll entsprechen:quelle
Der neueste swift3-Code funktioniert einwandfrei
quelle
Mit den in Swift 4.2 eingeführten neuen Funktionen habe ich einen ganz anderen Weg gefunden.
Wir haben eine Funktion mit Parametern deklariert, die ein Array von Strings nehmen und einen String zurückgeben.
Dann nehmen wir die ArrayOfStrings in eine Variable.
Es mischt im Grunde das Array von Strings und hat dann auch eine zufällige Auswahl der Anzahl der Gesamtzahl der Zählungen und gibt dann den zufälligen Index des gemischten Arrays zurück.
quelle