ฉันรู้ว่าหนังสือ Swift ได้จัดทำเครื่องมือสร้างตัวเลขแบบสุ่ม วิธีที่ดีที่สุดในการคัดลอกและวางการใช้งานนี้ในโปรแกรมของตัวเองหรือไม่ หรือว่ามีห้องสมุดที่เราสามารถใช้ตอนนี้ได้หรือไม่?
ฉันรู้ว่าหนังสือ Swift ได้จัดทำเครื่องมือสร้างตัวเลขแบบสุ่ม วิธีที่ดีที่สุดในการคัดลอกและวางการใช้งานนี้ในโปรแกรมของตัวเองหรือไม่ หรือว่ามีห้องสมุดที่เราสามารถใช้ตอนนี้ได้หรือไม่?
คำตอบ:
Swift 4.2+
Swift 4.2 มาพร้อมกับ Xcode 10 แนะนำฟังก์ชั่นสุ่มใหม่ที่ใช้งานง่ายสำหรับข้อมูลหลายประเภท คุณสามารถเรียกrandom()
วิธีการในประเภทตัวเลข
let randomInt = Int.random(in: 0..<6)
let randomDouble = Double.random(in: 2.71828...3.14159)
let randomBool = Bool.random()
ใช้arc4random_uniform(n)
สำหรับจำนวนเต็มแบบสุ่มระหว่าง 0 ถึง n-1
let diceRoll = Int(arc4random_uniform(6) + 1)
ส่งผลลัพธ์ไปที่ Int เพื่อที่คุณจะได้ไม่ต้องพิมพ์ vars ของคุณอย่างชัดเจนUInt32
(ซึ่งดูเหมือนว่าไม่น่าสนใจ)
0
แต่ลูกเต๋าที่เกิดขึ้นจริงไม่ได้ ในรหัสของคุณอาจจะเป็นdiceRoll
0
แค่พูดว่า ...
Int(arc4random_uniform(6)+1)
ใช่คุณต้องการจริงๆ
arc3random_uniform(n)
a UInt32(n)
หากคุณใช้ค่าที่ยังไม่ได้เป็นประเภทนั้น
แก้ไข: อัปเดตสำหรับ Swift 3.0
arc4random
ทำงานได้ดีใน Swift แต่ฟังก์ชั่นพื้นฐานนั้น จำกัด จำนวนเต็ม 32 บิต ( Int
64- บิตบน iPhone 5S และ Macs ทันสมัย) นี่คือฟังก์ชั่นทั่วไปสำหรับจำนวนสุ่มชนิดที่แสดงออกโดยตัวอักษรจำนวนเต็ม:
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)
. กรุณาแนะนำคุณหมายถึงอะไรที่นี่?
arc4random
(ที่กำหนดไว้ในการป้องกันรหัสแรก) อาร์กิวเมนต์ซึ่งเป็นUInt64
Type
arc4random_buf
มัน วัตถุประสงค์ของส่วนขยายเหล่านี้คือการทำสิ่งที่arc4random_uniform
จะทำ (บรรเทาความอคติโมดูโล) ยกเว้นประเภท 64 บิต
แก้ไขสำหรับ Swift 4.2
เริ่มต้นใน Swift 4.2 แทนที่จะใช้ฟังก์ชั่น C ที่นำเข้า arc4random_uniform () ตอนนี้คุณสามารถใช้ฟังก์ชั่นดั้งเดิมของ Swift ได้แล้ว
// Generates integers starting with 0 up to, and including, 10
Int.random(in: 0 ... 10)
คุณสามารถใช้random(in:)
เพื่อรับค่าสุ่มสำหรับค่าดั้งเดิมอื่น ๆ เช่นกัน; เช่น Int, Double, Float และแม้แต่ Bool
Swift เวอร์ชั่น <4.2
วิธีนี้จะสร้างInt
ค่าสุ่มระหว่างขั้นต่ำและสูงสุดที่กำหนด
func randomInt(min: Int, max: Int) -> Int {
return min + Int(arc4random_uniform(UInt32(max - min + 1)))
}
ฉันใช้รหัสนี้:
var k: Int = random() % 10;
random is unavailable in Swift: Use arc4random instead.
ในฐานะของ iOS 9 คุณสามารถใช้คลาส GameplayKit ใหม่เพื่อสร้างตัวเลขสุ่มได้หลายวิธี
คุณมีแหล่งที่มาสี่ประเภทให้เลือก: แหล่งสุ่มทั่วไป (ไม่มีชื่อลงไปที่ระบบเพื่อเลือกว่ามันทำอะไร), เชิงเส้นเชิงเส้นตรง, ARC4 และ Mersenne Twister สิ่งเหล่านี้สามารถสร้าง ints แบบสุ่มลอยและบูลส์
ในระดับที่ง่ายที่สุดคุณสามารถสร้างตัวเลขสุ่มจากแหล่งสุ่มในตัวของระบบดังนี้:
GKRandomSource.sharedRandom().nextInt()
ที่สร้างตัวเลขระหว่าง -2,147,483,648 ถึง 2,147,483,647 หากคุณต้องการตัวเลขระหว่าง 0 ถึงขอบเขตสูงสุด (พิเศษ) คุณจะใช้สิ่งนี้:
GKRandomSource.sharedRandom().nextIntWithUpperBound(6)
GameplayKit มีตัวสร้างความสะดวกสบายบางอย่างในตัวเพื่อทำงานกับลูกเต๋า ตัวอย่างเช่นคุณสามารถหมุนแม่พิมพ์แบบหกด้านดังนี้:
let d6 = GKRandomDistribution.d6()
d6.nextInt()
นอกจากนี้คุณสามารถกำหนดรูปแบบการกระจายแบบสุ่มโดยใช้สิ่งต่าง ๆ เช่น GKShuffledDistribution ที่จะอธิบายเล็ก ๆ น้อย ๆ แต่ถ้าคุณสนใจคุณสามารถอ่านการกวดวิชาของฉันในการสุ่มตัวเลข GameplayKit
import GameplayKit
ที่จะใช้ฟังก์ชั่นเหล่านี้เป็นหนึ่งในความต้องการที่จะเพิ่ม Swift 3 เปลี่ยนไวยากรณ์เป็นGKRandomSource.sharedRandom().nextInt(upperBound: 6)
คุณสามารถทำได้เช่นเดียวกับใน C:
let randomNumber = arc4random()
randomNumber
ถูกอนุมานว่าเป็นชนิดUInt32
(จำนวนเต็มที่ไม่ได้ลงชื่อ 32 บิต)
rand
, arc4random
, drand48
และเพื่อน ๆ ทุกคนในDarwin
โมดูล มีการนำเข้าแล้วสำหรับคุณหากคุณกำลังสร้างแอป Cocoa, UIKit หรือมูลนิธิ แต่คุณจะต้องimport Darwin
เล่นในสนามเด็กเล่น
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
วันสุ่มในเดือนตุลาคม
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 ()
นอกจากนี้คุณยังสามารถรับหมายเลขสุ่มโดยใช้arc4random()
ซึ่งสร้างUInt32
ระหว่าง 0 และ 2 ^ 32-1 ดังนั้นเพื่อให้ได้ตัวเลขสุ่มระหว่าง0
และx-1
คุณสามารถหารด้วยx
และหาส่วนที่เหลือ หรือกล่าวอีกนัยหนึ่งให้ใช้ตัวดำเนินการ Remainder (%) :
let number = arc4random() % 5 // 0...4
อย่างไรก็ตามนี่ทำให้เกิดอคติแบบโมดูโลเล็กน้อย(ดูที่นี่และที่นี่ ) นั่นคือเหตุผลarc4random_uniform()
แนะนำ
การแปลงไปและกลับจาก Int
โดยปกติจะเป็นการดีหากทำสิ่งนี้เพื่อแปลงไปมาระหว่างInt
และUInt32
:
let number: Int = 10
let random = Int(arc4random_uniform(UInt32(number)))
อย่างไรก็ตามปัญหาคือว่าInt
มีช่วงของ-2,147,483,648...2,147,483,647
ระบบ 32 บิตและช่วง-9,223,372,036,854,775,808...9,223,372,036,854,775,807
บนระบบ 64 บิต เปรียบเทียบนี้เพื่อช่วงของ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
ช่วงและคุณไม่ต้องการเอาต์พุตที่อยู่นอกช่วงนั้น
ตัวอย่างสำหรับหมายเลขสุ่มในระหว่าง 10 (0-9);
import UIKit
let randomNumber = Int(arc4random_uniform(10))
รหัสง่ายมาก - ง่ายและสั้น
ฉันสามารถใช้rand()
เพื่อรับ CInt แบบสุ่มได้ คุณสามารถทำให้มันเป็น Int ได้โดยใช้สิ่งนี้:
let myVar: Int = Int(rand())
คุณสามารถใช้ฟังก์ชันสุ่ม C ที่คุณชื่นชอบและเพียงแปลงเป็นค่าเป็น Int หากต้องการ
random()
ซึ่งจะส่งกลับInt
มากกว่าUInt32
- และเช่น @SomeGuy ที่กล่าวถึงเพียงโทรsrandom(arc4random())
หนึ่งครั้งก่อนที่จะใช้เพื่อให้แน่ใจว่ามีเมล็ดที่แตกต่างกันและสุ่มสำหรับการดำเนินการของแต่ละโปรแกรมของคุณ
คำตอบของ @jstnเป็นสิ่งที่ดี แต่ verbose เล็กน้อย 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()
และคลาสจำนวนเต็มอื่น ๆ ทั้งหมดก็โอเค
ใน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)
นี่คือห้องสมุดที่ทำงานได้ดี 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
}
}
let MAX : UInt32 = 9
let MIN : UInt32 = 1
func randomNumber()
{
var random_number = Int(arc4random_uniform(MAX) + MIN)
print ("random = ", random_number);
}
ฉันต้องการเพิ่มคำตอบที่มีอยู่ว่าตัวอย่างตัวสร้างตัวเลขสุ่มในหนังสือ Swift เป็น Linear Congruence Generator (LCG) มันเป็นข้อ จำกัด ที่รุนแรงมากและไม่ควรยกเว้นตัวอย่างที่น่ารำคาญซึ่งคุณภาพของการสุ่มไม่ได้ ไม่เป็นไร และLCG ไม่ควรที่จะใช้เพื่อวัตถุประสงค์ในการเข้ารหัสลับ
arc4random()
ดีกว่ามากและสามารถใช้เพื่อวัตถุประสงค์ส่วนใหญ่ได้ แต่ไม่ควรใช้อีกครั้งเพื่อจุดประสงค์การเข้ารหัส
SecCopyRandomBytes()
ถ้าคุณต้องการสิ่งที่รับประกันว่าจะมีความปลอดภัยเข้ารหัสการใช้งาน โปรดทราบว่าหากคุณสร้างตัวสร้างตัวเลขสุ่มเป็นบางสิ่งบางอย่างคนอื่นอาจลงเอยด้วยการใช้งานเพื่อจุดประสงค์ในการเข้ารหัส (เช่นรหัสผ่านการสร้างรหัสหรือการสร้างเกลือ) คุณควรพิจารณาใช้SecCopyRandomBytes()
ต่อไปแม้ว่าความต้องการของคุณจะไม่ได้ ไม่ต้องการสิ่งนั้น
มี API ชุดใหม่:
let randomIntFrom0To10 = Int.random(in: 0 ..< 10)
let randomDouble = Double.random(in: 1 ... 10)
ทั้งหมดเป็นตัวเลขประเภทในขณะนี้มีวิธีการที่จะใช้เวลาrandom(in:)
range
ส่งคืนตัวเลขที่กระจายอย่างสม่ำเสมอในช่วงนั้น
TL; DR
คุณต้องใช้นำเข้าC APIs (พวกเขามีความแตกต่างกันระหว่างแพลตฟอร์ม)
และยิ่งกว่านั้น ...
ถ้าฉันบอกคุณว่าการสุ่มไม่ใช่การสุ่ม
ถ้าคุณใช้arc4random()
(ในการคำนวณส่วนที่เหลือ)เช่นarc4random() % aNumber
ผลที่ไม่ได้กระจายอย่างสม่ำเสมอระหว่างและ0
aNumber
มีปัญหาที่เรียกว่าเป็นอคติ Modulo
อคติโมดูโล
โดยปกติการทำงานสร้างเลขสุ่มระหว่าง0
และMAX (ขึ้นอยู่กับประเภทอื่น ๆ ) ที่จะทำให้ได้อย่างรวดเร็วตัวอย่างง่ายสมมติว่าจำนวนสูงสุด7
และคุณสนใจเกี่ยวกับตัวเลขสุ่มในช่วง0 ..< 2
(หรือช่วง [0, 3) ถ้าคุณต้องการให้)
ความน่าจะเป็นสำหรับตัวเลขแต่ละคือ
ในคำอื่น ๆ ที่คุณมีแนวโน้มที่จะจบลงด้วย0หรือ1กว่า2 แน่นอนว่าต้องจำไว้ว่าสิ่งนี้ง่ายมากและหมายเลขMAXสูงกว่ามากทำให้ "ยุติธรรม" มากขึ้น
ปัญหานี้แก้ไขได้จากSE-0202 - การรวมกันแบบสุ่มในSwift 4.2
หากไม่มี arc4Random_uniform () ใน Xcode บางรุ่น (ใน 7.1 มันจะทำงาน แต่ไม่มีการเติมข้อความอัตโนมัติให้ฉัน) คุณสามารถทำสิ่งนี้แทน
เพื่อสร้างตัวเลขสุ่มตั้งแต่ 0-5 เป็นครั้งแรก
import GameplayKit
แล้วก็
let diceRoll = GKRandomSource.sharedRandom().nextIntWithUpperBound(6)
var randomNumber = Int(arc4random_uniform(UInt32(5)))
ที่นี่ 5 จะทำให้แน่ใจว่าตัวเลขสุ่มถูกสร้างผ่านศูนย์ถึงสี่ คุณสามารถตั้งค่าตามความเหมาะสม
สวิฟท์ 4.2
ลาก่อนเพื่อนำเข้า Foundation C lib 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()
รหัสต่อไปนี้จะสร้างตัวเลขสุ่มที่ปลอดภัยระหว่าง 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
s ที่จะใช้ในการสร้างหมายเลขสุ่ม บรรทัดสุดท้ายแปลง[UInt8]
ไปUInt16
หรือUInt32
หรือ
ฉันไม่รู้ว่าสองคนสุดท้ายยังนับว่าสุ่มอย่างแท้จริงหรือไม่ แต่คุณสามารถปรับแต่งมันตามความชอบของคุณ :)
สวิฟท์ 4.2
Swift 4.2 ได้รวม API สุ่มหมายเลขแบบดั้งเดิมและมีคุณสมบัติครบถ้วนในไลบรารีมาตรฐาน ( ข้อเสนอ Swift Evolution SE-0202 )
let intBetween0to9 = Int.random(in: 0...9)
let doubleBetween0to1 = Double.random(in: 0...1)
ประเภทตัวเลขทั้งหมดมีสแตติกสุ่ม (เป็น :)ซึ่งใช้ช่วงและส่งกลับหมายเลขสุ่มในช่วงที่กำหนด
สวิฟท์ 4.2, 10.1
สำหรับ iOS, MacOS และ tvOS คุณสามารถใช้ทั้งระบบแหล่งข้อมูลที่สุ่มGameKit
ในกรอบของ Xcode ที่นี่คุณสามารถค้นหา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)
คุณสามารถใช้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())
ฉันใช้รหัสนี้เพื่อสร้างตัวเลขสุ่ม:
//
// 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]
}
}
xCode 9.1, Swift 4
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
}
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]
อย่าลืมเพิ่มรหัสคณิตศาสตร์ (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]
}
}
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]
}