Apple의 Swift 언어에서 난수를 어떻게 생성합니까?


443

Swift 책이 난수 생성기의 구현을 제공한다는 것을 알고 있습니다. 이 구현을 자신의 프로그램에 복사하여 붙여 넣는 것이 가장 좋은 방법입니까? 아니면 지금 사용할 수있는 라이브러리가 있습니까?

답변:


466

스위프트 4.2 이상

Xcode 10과 함께 제공되는 Swift 4.2에는 다양한 데이터 유형에 사용하기 쉬운 새로운 임의 기능이 도입되었습니다. random()숫자 유형 에서 메소드를 호출 할 수 있습니다 .

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

7
Darwin을 명시 적으로 가져올 필요가 없었습니다.
finneycanhelp

3
내 놀이터 파일에서 다른 것을 가져 오지 않았기 때문에 Darwin을 가져와야했습니다.
DonnaLea

SoliQuiD : arc4 뒤에 여분의 밑줄을 생략합니다 (예 : arc4random_uniform (5)).
Ali Beadle

3
경고 : RC4 또는 ARC4이 표시되었습니다순수한 임의의 값을 구별 . 그래서 ARC4 (스트림 암호)가 있지만, 소리 , 안전한 암호화, 사실이 아니다.
Maarten Bodewes

2
@MaartenBodewes : 더 이상이 답변과 직접 관련이 없지만 arc4random은 이름에도 불구하고 macOS 또는 BSD에서 실제로 RC4 암호를 사용하지 않습니다. macOS에서는 시스템 제공 CSPRNG를 사용하고 대부분의 BSD에서는 ChaCha20을 사용합니다. Swift의 기본 RNG (이 답변에 사용 된)는 macOS에서 구현 세부 사항으로 부르지 만 지원되는 각 플랫폼에서 적절한 기본 생성기를 사용합니다.
Stephen Canon

496

arc4random_uniform(n)0과 n-1 사이의 임의의 정수에 사용하십시오 .

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

결과를 Int로 캐스팅하면 var를 명시 적으로 입력 할 필요가 없습니다 UInt32(Swifty가 아닌 것처럼 보입니다).


7
매우 간단합니다. 나는 그것을 좋아한다. 공감! 그러나 실제 주사위는 없습니다 0. 귀하의 코드에서는 일 diceRoll수 있습니다 0. 그냥 ...
MK Safi

61
예, 정말로 원합니다 Int(arc4random_uniform(6)+1).
Michael Dorst

5
확률 = Int (arc4random_uniform (UInt32 (total))) – 나는 또한 UInt32로 캐스팅했다
bshirley

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

N,에 입력 매개 변수, 캐스팅 잊지 마세요 arc3random_uniform(n)A를 UInt32(n)이미 해당 유형의 아닌 값을 사용하는 경우입니다.
Dave Fontenot

117

편집 : Swift 3.0 업데이트

arc4randomSwift에서는 잘 작동하지만 기본 기능은 32 비트 정수 유형 ( IntiPhone 5S 및 최신 Mac에서는 64 비트)으로 제한됩니다. 다음은 정수 리터럴로 표현할 수있는 임의의 숫자 유형에 대한 일반 함수입니다.

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

이 새로운 일반 함수를 사용하여 확장 UInt64하고 경계 인수를 추가하고 모듈러스 바이어스를 완화 할 수 있습니다 . (이것은 arc4random.c 에서 똑바로 들어 올려집니다 )

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
    }
}

이를 통해 우리는 Int64오버플로를 처리하면서 동일한 인수로 확장 할 수 있습니다 .

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
        }
    }
}

가족을 완성하려면 ...

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
        }
    }
}

결국, 우리는 마침내 다음과 같이 할 수 있습니다 :

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

컴파일되지 않습니다 : var r = arc4random(UInt64). 여기에 무슨 의미가 있었습니까?
Ossir

@Ossir는 나를 위해 잘 컴파일됩니다 ... 그것은 arc4random인수 UInt64인 첫 번째 코드 블록에 정의 된 함수를 호출하는 것을 의미 합니다 Type.
jstn

arc4random_buf (및 모든 64 비트 확장)가 모듈로 바이어스를 겪습니까?
Matthew Seaman

모듈러스 바이어스는 상한을 추가 할 때만 작동하므로에 적용되지 않습니다 arc4random_buf. 이러한 확장의 목적은 arc4random_uniform64 비트 유형을 제외하고 정확히 수행하는 것 (모듈로 바이어스 완화)입니다.
jstn

float 함수를 사용할 때 가능한 범위에 상위 값을 포함시키는 방법은 무엇입니까? 제가 0.0을 낮게하고 1.0을 위쪽으로한다고합시다. 이 논리를 사용하면 0.0에서 0.99999999까지를 얻을 수 있습니다. 그러나 대신 1.0을 가능성으로 포함하고 싶습니다. 어떻게하면 되나요?
MobileMon

80

스위프트 4.2 편집

가져온 C 함수 arc4random_uniform ()을 사용하는 대신 Swift 4.2부터 Swift 고유의 고유 함수를 사용할 수 있습니다.

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

random(in:)다른 기본 값에 대한 임의의 값을 얻는 데 사용할 수도 있습니다 . Int, Double, Float 및 Bool과 같은

스위프트 버전 <4.2

이 방법은 Int주어진 최소값과 최대 값 사이의 임의의 값 을 생성합니다

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

61

나는이 코드를 사용했다 :

var k: Int = random() % 10;

20
당신은 srandom를 호출해야합니다 (UINT32 (시간 (전무))) 첫째, 그렇지 않으면 항상 같은 번호 순서 반환합니다
안녕 간장 에듀 펠리 즈 Navidad입니다

3
random ()에 대한 Apple doc을 두 번 읽었지만 사용법을 얻을 수 없었습니다. 위에 간단한 코드 샘플을 포함시키기를 바랍니다. "random () 함수는 크기가 31 인 정수의 기본 테이블을 사용하는 비선형, 추가 피드백, 난수 생성기를 사용합니다. 0에서 (2 31) -1 사이의 연속적인 의사 난수를 반환합니다 . 이 난수 생성기의주기는 약 16 * ((2 31) -1) 로 매우 큽니다 . " ... 많은 사과 주셔서 감사합니다 ... 다음 논문에서 이것을 참조 할 것입니다.
nocarrier

1
random ()은 때때로 iPad에서 갑자기 충돌을 일으 킵니다. 이 경우 위에서 arc4random_uniform (6)을 사용하십시오. random ()을 사용하면 srandomdev ()를 앞에 추가하여 더 많은 임의의 값을 만들 수 있습니다.
JackPearse

1
컴파일러 오류 메시지가 나타납니다.random is unavailable in Swift: Use arc4random instead.
Mike Keskinov

1
이 솔루션에는 모듈로 바이어스가 있습니다. zuttobenkyou.wordpress.com/2012/10/18/…
rgov

33

iOS 9부터 새로운 GameplayKit 클래스를 사용하여 다양한 방법으로 난수를 생성 할 수 있습니다.

선택할 수있는 네 가지 소스 유형이 있습니다 : 일반 무작위 소스 (이름이없는, 시스템의 기능을 선택하는 시스템까지), 선형 일치 성, ARC4 및 Mersenne Twister. 이들은 임의의 정수, 부동 소수점 및 부울을 생성 할 수 있습니다.

가장 간단한 수준에서 다음과 같이 시스템의 내장 임의 소스에서 난수를 생성 할 수 있습니다.

GKRandomSource.sharedRandom().nextInt()

이는 -2,147,483,648과 2,147,483,647 사이의 숫자를 생성합니다. 0과 상한 (제외) 사이의 숫자를 원하면 다음을 사용하십시오.

GKRandomSource.sharedRandom().nextIntWithUpperBound(6)

GameplayKit에는 주사위와 함께 사용할 수있는 편리한 생성자가 있습니다. 예를 들어 다음과 같이 6 면체 주사위를 굴릴 수 있습니다.

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

또한 GKShuffledDistribution과 같은 것을 사용하여 무작위 분포를 형성 할 수 있습니다. 좀 더 설명이 필요하지만 관심이 있다면 GameplayKit 난수에 대한 튜토리얼을 읽을 .


1
이 팁에 감사드립니다. 가장 좋은 답변 중 하나입니다. 이 기능을 사용하려면 추가해야합니다 import GameplayKit. Swift 3의 구문이 다음과 같이 변경되었습니다 :GKRandomSource.sharedRandom().nextInt(upperBound: 6)
petrsyn

7
이 키트는 얼마나 무거워 집니까? 내 코드를 부풀리고 싶지 않습니다.
μολὼν.λαβέ

25

C에서와 동일한 방식으로 수행 할 수 있습니다.

let randomNumber = arc4random()

randomNumber유형 UInt32(32 비트 부호없는 정수) 인 것으로 추론됩니다.


12
부록은 : rand, arc4random, drand48과 친구들은 모두 있습니다 Darwin모듈. Cocoa, UIKit 또는 Foundation 앱을 빌드하는 경우 이미 가져 왔지만 import Darwin놀이터에서 해야합니다 .
rickster

5
그리고 arc4random ()의 결과를 Int로 캐스트하려고하지 마십시오. 이것은 64 비트 플랫폼에서는 잘 작동하지만 32 비트 플랫폼에서는 Ints에 32 비트 부호가 있으므로 예기치 않은 음수가 발생합니다. 번호. 이것은 이미 몇 사람을 넘어서서 여기에 언급하겠다고 생각했습니다.
매트 깁슨

23

사용하다 arc4random_uniform()

용법:

arc4random_uniform(someNumber: UInt32) -> UInt32

이 범위에서 당신에게 임의의 정수를 제공 0하는 someNumber - 1.

의 최대 값 UInt32은 4,294,967,295 (즉 2^32 - 1)입니다.

예 :

  • 동전 던지기

    let flip = arc4random_uniform(2) // 0 or 1
  • 주사위 롤

    let roll = arc4random_uniform(6) + 1 // 1...6
  • 10 월의 임의의 날

    let day = arc4random_uniform(31) + 1 // 1...31
  • 1990 년대의 무작위 연도

    let year = 1990 + arc4random_uniform(10)

일반적인 형태 :

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

어디에 number, max그리고 min있습니다 UInt32.

이건 어떤가요...

arc4random ()

0을 사용하여 2 ^ 32-1 arc4random()을 생성 하는 난수를 얻을 수도 있습니다 UInt32. 따라서 0와 사이에 임의의 숫자를 얻으려면 숫자를 x-1나누고 x나머지를 취할 수 있습니다 . 즉, 나머지 연산자 (%)를 사용하십시오 .

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

그러나 이것은 약간의 모듈로 바이어스를 생성하므로 ( 여기여기 참조 ) 이것이 arc4random_uniform()권장되는 이유 입니다.

와 (과) 변환 Int

일반적으로는 변환 후면과 등 사이에 위해 이런 일을 할 괜찮을 것 IntUInt32:

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

문제는, 그러나, 즉 Int범위 갖는 -2,147,483,648...2,147,483,64732 비트 시스템과의 범위를 -9,223,372,036,854,775,808...9,223,372,036,854,775,80764 개 비트 시스템에있다. 이것을의 UInt32범위와 비교하십시오 0...4,294,967,295. 의 U부호없는UInt32 것을 의미 합니다.

다음 오류를 고려하십시오.

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

따라서 입력 매개 변수가 UInt32범위 내에 있고 해당 범위를 벗어난 출력이 필요하지 않아야합니다.


19

10 (0-9)의 난수에 대한 예;

import UIKit

let randomNumber = Int(arc4random_uniform(10))

매우 쉬운 코드-간단하고 짧습니다.


16

난 그냥 rand()임의의 CInt를 얻기 위해 사용할 수있었습니다 . 다음과 같이 사용하여 Int로 만들 수 있습니다.

let myVar: Int = Int(rand())

좋아하는 C 랜덤 함수를 사용할 수 있으며 필요한 경우 값을 Int로 변환하면됩니다.


그러나 유형 변환은 까다로운 사업이 될 수 있으며 Int 생성자가 처리하는 것이 실제로 고통을 덜어줍니다.
Kzrbill

4
rand ()를 사용하기 전에 srand (...)를 호출하지 않으면 (한 번만 호출), 프로그램의 각 실행간에 숫자 순서가 항상 동일합니다. 이것을 원하지 않으면 arc4random ()
SomeGuy

2
@SomeGuy가 언급 한 것처럼- 대신 random()반환하는을 사용할 수도 있습니다. 사용 하기 전에 어디서나 한 번만 호출 하면 프로그램의 각 실행마다 다른 무작위 시드가 있는지 확인할 수 있습니다. IntUInt32srandom(arc4random())
brittlewis12

1
누구든지 rand () vs arc4random_uniform ()에 대해 언급 할 수 있습니까?
Ruben Martinez Jr.

16

@jstn의 대답 은 좋지만 조금 장황합니다. Swift는 프로토콜 지향 언어로 알려져 있으므로 프로토콜 확장에 기본 구현을 추가하여 정수 패밀리의 모든 클래스에 대해 상용구 코드를 구현하지 않고도 동일한 결과를 얻을 수 있습니다.

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

이제 우리는 할 수 있습니다 :

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

그리고 다른 모든 정수 클래스는 괜찮습니다.


11

Swift 4.2 에서는 random()원하는 숫자 유형에 대해 메소드를 호출하여 작업하려는 범위를 제공하여 난수를 생성 할 수 있습니다 . 예를 들어, 이것은 양쪽에서 1에서 9 사이의 난수를 생성합니다.

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

다른 유형과도

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

9

다음은 잘 작동하는 라이브러리입니다 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 책의 난수 생성기 예제가 선형 합동 생성기 (LCG)이며 기존의 답변에 추가하고 싶습니다. 전혀 중요하지 않습니다. 그리고 LCG 암호화 목적으로 사용해서는 안됩니다 .

arc4random()훨씬 낫고 대부분의 목적으로 사용될 수 있지만 암호화 목적으로 다시 사용 해서는 안됩니다.

암호화로 안전한 것을 원하면을 사용하십시오 SecCopyRandomBytes(). 난수 생성기를 무언가로 만들면 다른 사람이 암호 목적 (암호, 키 또는 소금 생성과 같은)을 위해 그것을 사용 SecCopyRandomBytes()하게 될 수 있습니다 (필요한 경우에도) 그럴 필요는 없습니다.


6

스위프트 4.2 부터

새로운 API 세트가 있습니다.

let randomIntFrom0To10 = Int.random(in: 0 ..< 10)
let randomDouble = Double.random(in: 1 ... 10)
  • 모든 숫자 유형에는 이제 random(in:)메소드가 range있습니다.

  • 해당 범위에 균일하게 분포 된 숫자를 반환합니다.


TL; DR

글쎄, "좋은"옛날 방식에 어떤 문제가 있는가?

  1. 가져온 C API 를 사용해야합니다 (플랫폼마다 다릅니다) .

  2. 그리고 ...

랜덤이 랜덤이 아니라고 말하면 어떻게 되나요?

와 같이 ( arc4random() 나머지 계산) 을 사용 arc4random() % aNumber하면 결과 0 와 사이에 균일하게 분포 되지 않습니다aNumber . 모듈로 바이어스 라는 문제가 있습니다 .

모듈로 바이어스

일반적으로 함수 사이의 난수를 생성 0하고 MAX는 (종류 등에 의존한다) . 빠르고 쉬운 예를 들어, 최대 숫자가 7있고 범위 내 임의의 숫자 0 ..< 2 (또는 원하는 경우 간격 [0, 3)에 관심 이 있다고 가정 해 봅시다 .

개별 숫자 의 확률 은 다음과 같습니다.

  • 0 : 3/8 = 37.5 %
  • 1 : 3/8 = 37.5 %
  • 2 : 2/8 = 25 %

즉, 당신은 가능성 으로 끝낼 수 0 또는 1 에 비해 2 . 물론 이것은 매우 단순화되고 MAX 숫자가 훨씬 높아서 더 "공정" 하다는 것을 명심하십시오 .

이 문제는 SE-0202- Swift 4.2의 임의 통합 으로 해결되었습니다.


5

Xcode의 일부 버전에서 arc4Random_uniform ()이 없으면 (7.1에서는 실행되지만 자동 완성되지는 않습니다). 대신이 작업을 수행 할 수 있습니다.

0-5에서 난수를 생성합니다. 먼저

import GameplayKit

그때

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

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

여기서 5는 난수가 0에서 4까지 생성되도록합니다. 그에 따라 값을 설정할 수 있습니다.


1
5를 전달하면 0에서 4까지 5 개의 가능한 결과가 반환됩니다. 0 ... 4
Leo Dabus

3

스위프트 4.2

파운데이션 C 라이브러리 가져 오기 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. random (in :)을 사용하여 범위에서 임의의 숫자를 생성합니다.
  2. randomElement ()는 범위가 비어 있으면 nil을 반환하므로 반환 된 Int를 줄 바꿈 하시겠습니까? 하자면.
  3. random (in :)을 사용하여 임의의 Double, Float 또는 CGFloat 및 random ()을 생성하여 임의의 Bool을 반환합니다.

더 @ 공식


2

다음 코드는 0에서 255 사이의 안전한 임의의 숫자를 생성합니다.

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

당신은 이것을 다음과 같이 부릅니다.

print(UInt8.random)

숫자가 클수록 복잡해집니다.
이것은 내가 생각해 낼 수있는 최선입니다.

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) }
  }
}

이 방법들은 여분의 난수 UInt8를 사용하여 난수를 만드는 데 사용될 수를 결정합니다 . 마지막 줄은 변환 [UInt8]UInt16UInt32.

마지막 두 가지가 여전히 무작위로 계산되는지는 모르겠지만 원하는대로 조정할 수 있습니다. :)


모듈로에 의한 바이어스, +1을 똑똑히 피했습니다. 독자에게 왜 그렇게했는지 경고 할 수 있습니다.
jww

흥미 롭습니다. 모듈로 바이어스가 여기에서 작동 할 것이라고 생각하지 않았습니다. 아마도 작은 숫자를 얻는 기회는 큰 숫자를 얻는 것과 같지 않습니다.
Zyphrax

2

스위프트 4.2

Swift 4.2는 표준 라이브러리에 기본 기능을 갖춘 모든 기능을 갖춘 난수 API를 포함했습니다. ( 스위프트 에볼루션 제안 SE-0202 )

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

모든 숫자 유형에는 정적 임의의 (in :) 이 있으며 범위를 가져 와서 주어진 범위의 임의의 숫자를 반환합니다


1

스위프트 4.2, Xcode 10.1 .

iOS, macOS 및 tvOS 의 경우 Xcode의 프레임 워크에서 시스템 전체의 임의 소스 를 사용할 수 있습니다 GameKit. 클래스 메소드를 GKRandomSource사용하여 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()

또는 randomElement()컬렉션의 임의 요소를 반환 하는 메서드를 사용하십시오 .

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

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

0

다음 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
피보나치는 어떻게 무작위입니까?
Nikolai Ruhe

안녕하세요 Nikolai,이 코드 블록은 이전 버전 Swift 1.2입니다. 새로운 Swift 2.0을 사용하는 경우 작동하지 않을 것입니다.
Durul Dalkanat

2
나는 이해하지만 여전히 질문에 요구 된 것과 같이 난수가 아닌 피보나치 생성기처럼 보입니다.
Nikolai Ruhe

0

이 코드를 사용하여 난수를 생성합니다.

//
//  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에 오신 것을 환영합니다. 코드 만 답변하지 않는 것이 좋습니다.이 코드가 질문에 답변하는 이유와 작동 방식을 설명하기 위해 답변을 편집하십시오. 자세한 내용은 stackoverflow.com/help/how-to-answer를 참조하십시오.
Tim Malone 2016 년

2
답변에 대한 컨텍스트를 제공하고 stackoverflow에 오신 것을 환영합니다. :)
Jonathan Eustace 2016 년

0

세부

x 코드 9.1, 스위프트 4

수학 중심의 솔루션 (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
}

솔루션 사용 (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]

프로그래머 중심 솔루션 (2)

수학 중심 솔루션 (1) 코드를 여기 에 추가하는 것을 잊지 마십시오

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]
    }
}

솔루션 사용 (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]

전체 샘플

여기 에 솔루션 (1) 및 솔루션 (2) 코드추가하는 것을 잊지 마십시오

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]
}

샘플 결과

여기에 이미지 설명을 입력하십시오


2
이 답변은 주제가 아닙니다. 문제는 난수를 생성하는 방법이었습니다. 난수 라이브러리를 만드는 방법이 아닙니다. esh.
Andrew Paul Simmons
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.