Apple'ın Swift dilinde rastgele bir sayı nasıl oluşturulur?


443

Swift kitabının rastgele sayı üretecinin uygulanmasını sağladığını anlıyorum. Bu uygulamayı kendi programına kopyalayıp yapıştırmak için en iyi uygulama var mı? Yoksa şimdi kullanabileceğimiz bir kütüphane var mı?

Yanıtlar:


466

Hızlı 4.2+

Xcode 10 ile birlikte gönderilen Swift 4.2, birçok veri türü için yeni, kullanımı kolay rastgele işlevler sunar. random()Yöntemi sayısal türlerde çağırabilirsiniz .

let randomInt = Int.random(in: 0..<6)
let randomDouble = Double.random(in: 2.71828...3.14159)
let randomBool = Bool.random()

7
Darwin'i açıkça ithal etmek zorunda değildim
finneycanhelp

3
Playground dosyamda Darwin'i ithal etmem gerekiyordu çünkü başka bir şey ithal etmiyordum.
DonnaLea

SoliQuiD: arc4'ten sonra ekstra alt çizgiyi atlamak hariç, yani arc4random_uniform (5).
Ali Beadle

3
Uyarı : RC4 ve ARC4 gösterilmiştir olduğu saf rastgele değerleri ayırt . Yani ARC4 (bir akış şifresi) her ne kadar sesler kriptografik, aslında değil.
Maarten Bodewes

2
@MaartenBodewes: artık bu cevapla doğrudan ilgili değil, ancak arc4random, ismine rağmen macOS veya BSD'lerde RC4 şifresini kullanmıyor. MacOS'ta sistem tarafından sağlanan CSPRNG ve çoğu BSD'de ChaCha20 kullanır. Swift'in varsayılan RNG'si (bu cevapta kullanıldığı gibi) bunu macOS'ta bir uygulama detayı olarak adlandırır, ancak desteklenen her platformda uygun bir temel oluşturucu kullanır.
Stephen Canon

496

arc4random_uniform(n)0 ile n-1 arasında rastgele bir tamsayı için kullanın .

let diceRoll = Int(arc4random_uniform(6) + 1)

Sonucu Int olarak UInt32yayınlayın, böylece varslerinizi açıkça (Swifty gibi görünüyor) olarak yazmak zorunda kalmazsınız .


7
Çok basit. Bunu sevdim. Oyla! Ama gerçek bir zar yok 0. Kodunuzda diceRollolabilir 0. Sadece söyleyerek ...
MK Safi

61
Evet, gerçekten istiyorsun Int(arc4random_uniform(6)+1).
Michael Dorst

5
olasılık = Int (arc4random_uniform (UInt32 (toplam))) - ben de UInt32'ye dökmek zorunda kaldım
bshirley

4
let randomElementInArray = Int (arc4random_uniform (array.count))
cmario

Girilen n parametresini yayınlamayı unutmayın arc3random_uniform(n) a UInt32(n)Zaten bu türde olmayan bir değer kullanıyorsanız.
Dave Fontenot

117

Düzenleme: Swift 3.0 için güncellendi

arc4randomSwift'te iyi çalışır, ancak temel işlevler 32 bit tamsayı türleriyle sınırlıdır ( IntiPhone 5S ve modern Mac'lerde 64 bittir). Tamsayı değişmez değeri ile ifade edilebilen rastgele bir sayı türü için genel bir işlev şunlardır:

public func arc4random<T: ExpressibleByIntegerLiteral>(_ type: T.Type) -> T {
    var r: T = 0
    arc4random_buf(&r, MemoryLayout<T>.size)
    return r
}

Bu yeni genel işlevi genişletmek UInt64, sınır argümanları eklemek ve modulo yanlılığını azaltmak için kullanabiliriz. (Bu doğrudan arc4random.c'den kaldırılır. )

public extension UInt64 {
    public static func random(lower: UInt64 = min, upper: UInt64 = max) -> UInt64 {
        var m: UInt64
        let u = upper - lower
        var r = arc4random(UInt64.self)

        if u > UInt64(Int64.max) {
            m = 1 + ~u
        } else {
            m = ((max - (u * 2)) + 1) % u
        }

        while r < m {
            r = arc4random(UInt64.self)
        }

        return (r % u) + lower
    }
}

Bununla, Int64taşma ile ilgili aynı argümanları uzatabiliriz :

public extension Int64 {
    public static func random(lower: Int64 = min, upper: Int64 = max) -> Int64 {
        let (s, overflow) = Int64.subtractWithOverflow(upper, lower)
        let u = overflow ? UInt64.max - UInt64(~s) : UInt64(s)
        let r = UInt64.random(upper: u)

        if r > UInt64(Int64.max)  {
            return Int64(r - (UInt64(~lower) + 1))
        } else {
            return Int64(r) + lower
        }
    }
}

Aileyi tamamlamak için ...

private let _wordSize = __WORDSIZE

public extension UInt32 {
    public static func random(lower: UInt32 = min, upper: UInt32 = max) -> UInt32 {
        return arc4random_uniform(upper - lower) + lower
    }
}

public extension Int32 {
    public static func random(lower: Int32 = min, upper: Int32 = max) -> Int32 {
        let r = arc4random_uniform(UInt32(Int64(upper) - Int64(lower)))
        return Int32(Int64(r) + Int64(lower))
    }
}

public extension UInt {
    public static func random(lower: UInt = min, upper: UInt = max) -> UInt {
        switch (_wordSize) {
            case 32: return UInt(UInt32.random(UInt32(lower), upper: UInt32(upper)))
            case 64: return UInt(UInt64.random(UInt64(lower), upper: UInt64(upper)))
            default: return lower
        }
    }
}

public extension Int {
    public static func random(lower: Int = min, upper: Int = max) -> Int {
        switch (_wordSize) {
            case 32: return Int(Int32.random(Int32(lower), upper: Int32(upper)))
            case 64: return Int(Int64.random(Int64(lower), upper: Int64(upper)))
            default: return lower
        }
    }
}

Tüm bunlardan sonra, nihayet böyle bir şey yapabiliriz:

let diceRoll = UInt64.random(lower: 1, upper: 7)

Bu derleme değil: var r = arc4random(UInt64). Lütfen burada ne demek istediğini tavsiye et.
Ossir

@Ossir benim için iyi derler ... Bu, arc4random(ilk kod bloğunda tanımlanan) işlevi UInt64bir Type.
jstn

Arc4random_buf (ve dolayısıyla 64 bit uzantıların tümü) modulo sapmasından muzdarip mi?
Matthew Seaman

Modulo önyargı sadece bir üst sınır eklediğinizde devreye girer, bu nedenle geçerli değildir arc4random_buf. Bu uzantıların amacı, arc4random_uniform64-bit tipleri dışında tam olarak ne yaptığını (modulo yanlılığını azaltmak) yapmaktır .
jstn

şamandıra işlevlerini kullanırken, olasılıklar aralığındaki üst değeri nasıl dahil edebilirim? Diyelim ki altta 0.0, üstte 1.0 yapıyorum. Bu mantıkla bana 0.0 ila 0.99999999 verecektir. Ama bunun yerine 1.0'ı olasılık olarak dahil etmek istiyorum. Bunu nasıl başarabilirim?
MobileMon

80

Swift 4.2 için Düzenle

Swift 4.2'den başlayarak, içe aktarılan arc4random_uniform () C işlevini kullanmak yerine, artık Swift'in kendi yerel işlevlerini kullanabilirsiniz.

// Generates integers starting with 0 up to, and including, 10
Int.random(in: 0 ... 10)

random(in:)Diğer ilkel değerler için de rasgele değerler elde etmek için kullanabilirsiniz ; Int, Double, Float ve hatta Bool gibi.

Swift sürümleri <4.2

Bu yöntem Int, verilen minimum ve maksimum arasında rastgele bir değer oluşturur

func randomInt(min: Int, max: Int) -> Int {
    return min + Int(arc4random_uniform(UInt32(max - min + 1)))
}

61

Bu kodu kullandım:

var k: Int = random() % 10;

20
önce srandom'u (UInt32 (time (nil))) çağırmalısınız, aksi takdirde her zaman aynı sayı dizisini döndürür
Hola Soy Edu Feliz Navidad

3
Ben elma doc rastgele () iki kez okumak ama kullanımını anlayamadım ... Keşke onlar sadece yukarıdaki gibi böyle basit bir kod örneği dahil. "Random () işlevi, 31 boy uzunluğunda tamsayıların varsayılan bir tablosunu kullanan doğrusal olmayan, toplamsal bir geri bildirim, rasgele sayı üreteci kullanır. 0 ile (2 31) -1 aralığında birbirini izleyen sözde rasgele sayılar döndürür . bu rasgele sayı üretecinin süresi çok büyük, yaklaşık 16 * ((2 31) -1). " ... Çok teşekkürler elma ... Bir sonraki tezimde buna değineceğim.
nocarrier

1
random () bazen iPad'lerde ani bir çökmeye neden olur. Bu olursa, yukarıdan arc4random_uniform (6) kullanın. Random () kullanırsanız, srandomdev () öğesini başlatarak daha fazla rastgele değer oluşturabilirsiniz.
JackPearse

1
Derleyici hata mesajı aldım:random is unavailable in Swift: Use arc4random instead.
Mike Keskinov

1
Bu çözümün modulo önyargısı vardır: zuttobenkyou.wordpress.com/2012/10/18/…
rgov

33

İOS 9'dan itibaren, çeşitli şekillerde rastgele sayılar üretmek için yeni GameplayKit sınıflarını kullanabilirsiniz.

Seçebileceğiniz dört kaynak türünüz vardır: genel bir rastgele kaynak (isimsiz, ne yapacağını seçmek için sisteme kadar), doğrusal uyumlu, ARC4 ve Mersenne Twister. Bunlar rastgele ints, float ve bools üretebilir.

En basit seviyede, sistemin yerleşik rastgele kaynağından rastgele bir sayı oluşturabilirsiniz:

GKRandomSource.sharedRandom().nextInt()

Bu -2.147.483.648 ile 2.147.483.647 arasında bir sayı üretir. 0 ile üst sınır (özel) arasında bir sayı istiyorsanız bunu kullanırsınız:

GKRandomSource.sharedRandom().nextIntWithUpperBound(6)

GameplayKit, zarlarla çalışmak için yerleşik bazı kullanışlı kuruculara sahiptir. Örneğin, altı taraflı bir kalıbı şu şekilde yuvarlayabilirsiniz:

let d6 = GKRandomDistribution.d6()
d6.nextInt()

Ayrıca GKShuffledDistribution gibi şeyleri kullanarak rastgele dağılımı şekillendirebilirsiniz. Bu biraz daha açıklamak gerekiyor, ancak ilgileniyorsanız GameplayKit rastgele sayılarla ilgili eğitimimi okuyabilirsiniz .


1
Bu ipucu için teşekkürler, en iyi cevaplardan biri. Bu işlevleri kullanabilmek için eklemeniz gerekir import GameplayKit. Swift 3 sözdizimini değiştirdiGKRandomSource.sharedRandom().nextInt(upperBound: 6)
petrsyn

7
bu kit ithal etmek ne kadar ağır? kodumu şişirmek istemiyorum.
μολὼν.λαβέ

25

C ile aynı şekilde yapabilirsiniz:

let randomNumber = arc4random()

randomNumbertüründen türetilmiştir UInt32(32 bit işaretsiz tam sayı)


12
Ek: rand, arc4random, drand48ve arkadaşlar tüm olan Darwinmodül. Bir Kakao, UIKit veya Vakıf uygulaması oluşturuyorsanız zaten sizin için içe aktarılmıştır, ancak import Darwinoyun alanlarında ihtiyacınız olacaktır .
rickster

5
Ve arc4random () sonucunu bir Int'ye yayınlamaya çalışmayın - bu 64 bit bir platformda iyi çalışır, ancak 32 bit bir platformda Ints 32 bit imzalıdır, bu yüzden beklenmedik negatif olur sayılar. Bu zaten birkaç kişiyi harekete geçirdi, bu yüzden burada bahsettiğimi düşündüm.
Matt Gibson

23

kullanım arc4random_uniform()

Kullanımı:

arc4random_uniform(someNumber: UInt32) -> UInt32

Bu aralıkta size rasgele tamsayılar verir 0etmek someNumber - 1.

İçin maksimum değer UInt324.294.967.295'tir (yani 2^32 - 1).

Örnekler:

  • Yazı tura

    let flip = arc4random_uniform(2) // 0 or 1
  • Zar atma

    let roll = arc4random_uniform(6) + 1 // 1...6
  • Ekim ayında rastgele gün

    let day = arc4random_uniform(31) + 1 // 1...31
  • 1990'larda rastgele yıl

    let year = 1990 + arc4random_uniform(10)

Genel form:

let number = min + arc4random_uniform(max - min + 1)

nerede number,, maxve minvardır UInt32.

Ne dersin...

arc4random ()

Ayrıca 0 ile 2 ^ 32-1 arasında arc4random()bir sayı üreten rasgele bir sayı da alabilirsiniz UInt32. Böylece arasında rastgele bir sayı almak 0ve x-1bunu aşağıdaki şekilde bölebilirsiniz xve kalanı alır. Başka bir deyişle, Kalan Operatör'ü (%) kullanın :

let number = arc4random() % 5 // 0...4

Bununla birlikte, bu hafif modulo önyargılarını üretir (ayrıca buraya ve buraya bakın ), bu yüzden arc4random_uniform()tavsiye edilir.

Dönüştürme ve dönüştürme Int

Normalde dönüştürme arkasına ileri arasına sırayla böyle bir şey yapmak için iyi olurdu Intve UInt32:

let number: Int = 10
let random = Int(arc4random_uniform(UInt32(number)))

Sorun olsa da, yani Intyelpazesine sahiptir -2,147,483,648...2,147,483,64732 bit sistemlerde ve bir dizi -9,223,372,036,854,775,808...9,223,372,036,854,775,80764 bit sistemlerde. Bunu, UInt32aralığıyla karşılaştırın 0...4,294,967,295. UArasında UInt32vasıtasıyla imzasız .

Aşağıdaki hataları göz önünde bulundurun:

UInt32(-1) // negative numbers cause integer overflow error
UInt32(4294967296) // numbers greater than 4,294,967,295 cause integer overflow error

Bu nedenle, giriş parametrelerinizin UInt32aralık dahilinde olduğundan ve bu aralığın dışında bir çıkışa ihtiyacınız olmadığından emin olmanız gerekir.


19

10 (0-9) arasında rastgele sayı örneği;

import UIKit

let randomNumber = Int(arc4random_uniform(10))

Çok kolay kod - basit ve kısa.


16

Sadece rand()rastgele bir CInt elde etmek için kullanabildim . Bunun gibi bir şey kullanarak bir Int yapabilirsiniz:

let myVar: Int = Int(rand())

En sevdiğiniz C rasgele işlevini kullanabilir ve gerekirse Int değerine dönüştürebilirsiniz.


Evet, tip dönüşümü zor bir iş olabilir ve Int yapıcısının onunla başa çıkmasına izin vermek gerçek bir ağrı tasarrufu sağlar.
Kzrbill

4
Rand () işlevini kullanmadan önce srand (...) (yalnızca bir kez arayın) aramıyorsanız, sayı dizisinin programınızın her yürütülmesi arasında her zaman tam olarak aynı olacağını unutmayın. Bunu istemiyorsanız, arc4random () kullanın
SomeGuy

2
Ayrıca random(), Intyerine bir döndüren de kullanabilirsiniz UInt32- ve bahsedilen @SomeGuy gibi srandom(arc4random()), programınızın her yürütülmesi için farklı, rastgele bir tohuma sahip olduğundan emin olmak için kullanmadan önce bir kez arayın .
brittlewis12

1
Herkes arc4random_uniform () vs rand () hakkında yorum yapabilir?
Ruben Martinez Jr.

16

@ jstn'in cevabı iyi, ama biraz ayrıntılı. Swift, protokol yönelimli bir dil olarak bilinir, bu nedenle, protokol uzantısı için varsayılan bir uygulama ekleyerek tamsayı ailesindeki her sınıf için kaynak plakası kodu uygulamak zorunda kalmadan aynı sonucu elde edebiliriz.

public extension ExpressibleByIntegerLiteral {
    public static func arc4random() -> Self {
        var r: Self = 0
        arc4random_buf(&r, MemoryLayout<Self>.size)
        return r
    }
}

Şimdi yapabiliriz:

let i = Int.arc4random()
let j = UInt32.arc4random()

ve diğer tüm tamsayı sınıfları uygundur.


11

In Swift 4.2 Eğer arayarak rasgele sayılar üretebilirsiniz random(), istediğiniz sayısal türü ne olursa olsun üzerinde yöntemini size çalışmak istediğiniz alternatifi sağlar. Örneğin, bu, her iki taraf da dahil olmak üzere 1-9 aralığında rastgele bir sayı oluşturur

let randInt = Int.random(in: 1..<10)

Diğer tiplerle de

let randFloat = Float.random(in: 1..<20)
let randDouble = Double.random(in: 1...30)
let randCGFloat = CGFloat.random(in: 1...40)

9

İşte işi iyi yapan bir kütüphane https://github.com/thellimist/SwiftRandom

public extension Int {
    /// SwiftRandom extension
    public static func random(lower: Int = 0, _ upper: Int = 100) -> Int {
        return lower + Int(arc4random_uniform(UInt32(upper - lower + 1)))
    }
}

public extension Double {
    /// SwiftRandom extension
    public static func random(lower: Double = 0, _ upper: Double = 100) -> Double {
        return (Double(arc4random()) / 0xFFFFFFFF) * (upper - lower) + lower
    }
}

public extension Float {
    /// SwiftRandom extension
    public static func random(lower: Float = 0, _ upper: Float = 100) -> Float {
        return (Float(arc4random()) / 0xFFFFFFFF) * (upper - lower) + lower
    }
}

public extension CGFloat {
    /// SwiftRandom extension
    public static func random(lower: CGFloat = 0, _ upper: CGFloat = 1) -> CGFloat {
        return CGFloat(Float(arc4random()) / Float(UINT32_MAX)) * (upper - lower) + lower
    }
}

8
 let MAX : UInt32 = 9
 let MIN : UInt32 = 1

    func randomNumber()
{
    var random_number = Int(arc4random_uniform(MAX) + MIN)
    print ("random = ", random_number);
}

6

Swift kitabındaki rasgele sayı üreteci örneğinin Doğrusal Bir Uyum Üreteci (LCG) olduğu, mevcut cevaplara eklemek istiyorum, ciddi bir sınırlamadır ve rastlantısallık kalitesinin olmadığı, önemsiz örnekler dışında olmamalıdır hiç önemli değil. Ve bir LCG asla kriptografik amaçlar için kullanılmamalıdır .

arc4random()çok daha iyidir ve çoğu amaç için kullanılabilir, ancak yine kriptografik amaçlar için kullanılmamalıdır.

Kriptografik olarak güvenli olduğu garanti edilen bir şey istiyorsanız, kullanın SecCopyRandomBytes(). Bir şeye rastgele bir sayı oluşturucu oluşturursanız, başkası şifreleme amacıyla (parola, anahtar veya tuz üretimi gibi) kullanabileceğini (yanlış) ortaya çıkarabileceğini unutmayın, o zaman SecCopyRandomBytes()ihtiyacınız olmasa bile yine de kullanmayı düşünmelisiniz . t Bunu kesinlikle gerektirmez.


6

Swift 4.2'den beri

Yeni bir API grubu var:

let randomIntFrom0To10 = Int.random(in: 0 ..< 10)
let randomDouble = Double.random(in: 1 ... 10)
  • Artık tüm sayısal türlerde kullanılan random(in:)yöntem vardır range.

  • Bu aralıkta eşit olarak dağıtılmış bir sayı döndürür.


TL; DR

Peki, "iyi" eski yolun sorunu ne?

  1. İçe aktarılan C API'larını kullanmanız gerekir (Bunlar platformlar arasında farklıdır) .

  2. Ve dahası...

Ya rastgele rastgele olmadığını söylersem?

Eğer kullanmak arc4random() (kalan hesaplamak için) gibi arc4random() % aNumber, sonuç değildir muntazam biçimde dağıtılmış 0ve aNumber. Modulo yanlılığı adı verilen bir sorun var .

Modulo önyargı

Normalde, işlev 0ve MAX arasında rastgele bir sayı üretir (türe bağlı olarak vb.) . Hızlı ve kolay bir örnek vermek gerekirse, diyelim ki maksimum sayı 7ve aralıktaki rastgele bir sayıyı 0 ..< 2 (veya isterseniz [0, 3)) önemsediğinizi varsayalım .

Olasılıkları tek tek sayılar için şunlardır:

  • 0: 3/8 =% 37,5
  • 1: 3/8 =% 37,5
  • 2: 2/8 =% 25

Başka bir deyişle, 0 veya 1 ile sonuçlanma olasılığınız 2'den fazladır . Tabii ki, bunun son derece basitleştirildiğini ve MAX sayısının çok daha yüksek olduğunu ve daha "adil" hale getirdiğini unutmayın.

Bu sorun tarafından ele alınmaktadır Rastgele birleşme - SE-0202 yılında Swift 4.2


5

Bazı Xcode sürümlerinde arc4Random_uniform () olmadan (7.1'de çalışır, ancak benim için otomatik tamamlanmaz). Bunun yerine bunu yapabilirsiniz.

0-5 arasında rastgele bir sayı üretmek için. İlk

import GameplayKit

Sonra

let diceRoll = GKRandomSource.sharedRandom().nextIntWithUpperBound(6)

5
var randomNumber = Int(arc4random_uniform(UInt32(5)))

Burada 5 rasgele sayının sıfırdan dörde üretildiğinden emin olacaktır. Değeri buna göre ayarlayabilirsiniz.


1
5'i geçerseniz, sıfırdan dörde 5 olası sonuç döndürür. 0 ... 4
Leo Dabus

3

Hızlı 4.2

Güle güle Vakfı C kütüphanesini ithal edecek arc4random_uniform()

// 1  
let digit = Int.random(in: 0..<10)

// 2
if let anotherDigit = (0..<10).randomElement() {
  print(anotherDigit)
} else {
  print("Empty range.")
}

// 3
let double = Double.random(in: 0..<1)
let float = Float.random(in: 0..<1)
let cgFloat = CGFloat.random(in: 0..<1)
let bool = Bool.random()
  1. Aralıklardan rastgele rakamlar oluşturmak için rasgele (içinde :) kullanırsınız.
  2. randomElement (), aralık boşsa nil döndürür, böylece döndürülen Int? izin verirseniz.
  3. Rasgele bir Double, Float veya CGFloat oluşturmak için random (in :) ve random Bool döndürmek için random () kullanırsınız.

Daha fazla @ Resmi


2

Aşağıdaki kod 0 ile 255 arasında güvenli bir rasgele sayı üretecektir:

extension UInt8 {
  public static var random: UInt8 {
    var number: UInt8 = 0
    _ = SecRandomCopyBytes(kSecRandomDefault, 1, &number)
    return number
  }
}

Buna şöyle diyorsunuz:

print(UInt8.random)

Daha büyük sayılar için daha karmaşık hale gelir.
Bu ben gelip en iyisi:

extension UInt16 {
  public static var random: UInt16 {
    let count = Int(UInt8.random % 2) + 1
    var numbers = [UInt8](repeating: 0, count: 2)
    _ = SecRandomCopyBytes(kSecRandomDefault, count, &numbers)
    return numbers.reversed().reduce(0) { $0 << 8 + UInt16($1) }
  }
}

extension UInt32 {
  public static var random: UInt32 {
    let count = Int(UInt8.random % 4) + 1
    var numbers = [UInt8](repeating: 0, count: 4)
    _ = SecRandomCopyBytes(kSecRandomDefault, count, &numbers)
    return numbers.reversed().reduce(0) { $0 << 8 + UInt32($1) }
  }
}

Bu yöntemler UInt8, rastgele sayıyı oluşturmak için kaç tane s kullanılacağını belirlemek için fazladan rastgele bir sayı kullanır . Son satır dönüştürür [UInt8]için UInt16ya UInt32.

Son ikisinin hala gerçekten rastgele sayılıp sayılmadığını bilmiyorum, ancak beğenilerinize göre değiştirebilirsiniz :)


Modulo tarafından ortaya konulan önyargıdan akıllıca kaçındınız, bunun için +1. Okuyucuları bunu neden yaptığınız konusunda uyarabilirsiniz.
jww

Bu ilginç, gerçekten modulo önyargının burada olabileceğini düşünmedim. Belki de küçük bir sayı elde etme şansı, büyük bir sayı elde etmekle aynı şey değildir.
Zyphrax

2

Hızlı 4.2

Swift 4.2, standart kütüphaneye yerel ve oldukça özellikli bir rasgele sayı API'sı ekledi. ( Swift Evrim önerisi SE-0202 )

let intBetween0to9 = Int.random(in: 0...9) 
let doubleBetween0to1 = Double.random(in: 0...1)

Tüm sayı türlerinde , aralığı alan ve verilen aralıktaki rastgele sayıyı döndüren statik rasgele (in :) bulunur


1

Swift 4.2, Xcode 10.1 .

İOS, macOS ve tvOS için sistem genelinde rastgele bir kaynağı Xcode çerçevesinde kullanabilirsiniz GameKit. Sınıf yöntemiyle GKRandomSourcesınıfı burada bulabilirsiniz sharedRandom():

import GameKit

let number: [Int] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

func randomGenerator() -> Int {
    let random = GKRandomSource.sharedRandom().nextInt(upperBound: number.count)
    return number[random]
}
randomGenerator()

Veya randomElement()koleksiyonun rastgele bir öğesini döndüren bir yöntem kullanın :

let number: [Int] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

let randomNumber = number.randomElement()!
print(randomNumber)

0

Bunun gibi kullanabilirsiniz GeneratorOf:

var fibs = ArraySlice([1, 1])
var fibGenerator = GeneratorOf{
    _ -> Int? in
    fibs.append(fibs.reduce(0, combine:+))
    return fibs.removeAtIndex(0)
}

println(fibGenerator.next())
println(fibGenerator.next())
println(fibGenerator.next())
println(fibGenerator.next())
println(fibGenerator.next())
println(fibGenerator.next())

3
Fibonacci nasıl rastgele?
Nikolai Ruhe

Merhaba Nikolai, Bu kod bloğu eski sürüm Swift 1.2. Yeni Swift 2.0'ı denerseniz. İş olmazdı.
Durul Dalkanat

2
Anlıyorum, ama yine de bana sorulan gibi rastgele sayılar değil, bir fibonacci jeneratörü gibi görünüyor.
Nikolai Ruhe

0

Rastgele bir sayı oluşturmak için bu kodu kullanın:

//
//  FactModel.swift
//  Collection
//
//  Created by Ahmadreza Shamimi on 6/11/16.
//  Copyright © 2016 Ahmadreza Shamimi. All rights reserved.
//

import GameKit

struct FactModel {

    let fun  = ["I love swift","My name is Ahmadreza","I love coding" ,"I love PHP","My name is ALireza","I love Coding too"]


    func getRandomNumber() -> String {

        let randomNumber  = GKRandomSource.sharedRandom().nextIntWithUpperBound(fun.count)

        return fun[randomNumber]
    }
}

2
SO hoş geldiniz. Yalnızca kod yanıtları önerilmemektedir - lütfen bu kodun soruyu neden yanıtladığını ve nasıl çalıştığını açıklamak için yanıtınızı düzenleyin. Daha fazla bilgi için stackoverflow.com/help/how-to-answer adresine bakın.
Tim Malone

2
Lütfen cevabınıza bir bağlam sağlayın ve stackoverflow'a hoş geldiniz. :)
Jonathan Eustace

0

ayrıntılar

xCode 9.1, Swift 4

Matematik odaklı çözüm (1)

import Foundation

class Random {

    subscript<T>(_ min: T, _ max: T) -> T where T : BinaryInteger {
        get {
            return rand(min-1, max+1)
        }
    }
}

let rand = Random()

func rand<T>(_ min: T, _ max: T) -> T where T : BinaryInteger {
    let _min = min + 1
    let difference = max - _min
    return T(arc4random_uniform(UInt32(difference))) + _min
}

Çözelti kullanımı (1)

let x = rand(-5, 5)       // x = [-4, -3, -2, -1, 0, 1, 2, 3, 4]
let x = rand[0, 10]       // x = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

Programcı odaklı çözüm (2)

Buraya Matematik odaklı çözüm (1) kodu eklemeyi unutmayın

import Foundation

extension CountableRange where Bound : BinaryInteger {

    var random: Bound {
        return rand(lowerBound-1, upperBound)
    }
}

extension CountableClosedRange where Bound : BinaryInteger {

    var random: Bound {
        return rand[lowerBound, upperBound]
    }
}

Çözelti kullanımı (2)

let x = (-8..<2).random           // x = [-8, -7, -6, -5, -4, -3, -2, -1, 0, 1]
let x = (0..<10).random           // x = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
let x = (-10 ... -2).random       // x = [-10, -9, -8, -7, -6, -5, -4, -3, -2]

Tam Örnek

Çözüm (1) ve çözüm (2) kodlarını buraya eklemeyi unutmayın

private func generateRandNums(closure:()->(Int)) {

    var allNums = Set<Int>()
    for _ in 0..<100 {
        allNums.insert(closure())
    }
    print(allNums.sorted{ $0 < $1 })
}

generateRandNums {
    (-8..<2).random
}

generateRandNums {
    (0..<10).random
}

generateRandNums {
    (-10 ... -2).random
}

generateRandNums {
    rand(-5, 5)
}
generateRandNums {
    rand[0, 10]
}

Örnek sonuç

resim açıklamasını buraya girin


2
Bu cevap konu dışı. Soru, rastgele bir sayının nasıl üretileceği idi. Rasgele sayı kitaplığı nasıl yapılır. Sheesh.
Andrew Paul Simmons
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.