简体   繁体   English

Swift中如何生成随机数?

[英]How to generate a random number in Swift?

I realize the Swift book provided an implementation of a random number generator.我实现了 Swift 这本书提供了一个随机数生成器的实现。 Is the best practice to copy and paste this implementation?复制和粘贴此实现的最佳做法是什么? Or is there a library that does this that we can use now?或者有没有我们现在可以使用的库?

Swift 4.2+斯威夫特 4.2+

Swift 4.2 shipped with Xcode 10 introduces new easy-to-use random functions for many data types. Xcode 10 附带的 Swift 4.2 为许多数据类型引入了新的易于使用的随机函数。 You can call the random() method on numeric types.您可以对数字类型调用random()方法。

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

Use arc4random_uniform(n) for a random integer between 0 and n-1.arc4random_uniform(n)用于 0 到 n-1 之间的随机整数。

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

Cast the result to Int so you don't have to explicitly type your vars as UInt32 (which seems un-Swifty).将结果转换为 Int,这样您就不必将您的变量显式键入为UInt32 (这似乎不是 Swifty)。

Edit: Updated for Swift 3.0编辑:为 Swift 3.0 更新

arc4random works well in Swift, but the base functions are limited to 32-bit integer types ( Int is 64-bit on iPhone 5S and modern Macs). arc4random在 Swift 中运行良好,但基本函数仅限于 32 位整数类型(在 iPhone 5S 和现代 Mac 上Int是 64 位)。 Here's a generic function for a random number of a type expressible by an integer literal:这是一个可以用整数文字表示的类型的随机数的通用函数:

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

We can use this new generic function to extend UInt64 , adding boundary arguments and mitigating modulo bias.我们可以使用这个新的通用函数来扩展UInt64 ,添加边界参数并减轻模偏差。 (This is lifted straight from arc4random.c ) (这是直接从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
    }
}

With that we can extend Int64 for the same arguments, dealing with overflow:有了它,我们可以为相同的参数扩展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
        }
    }
}

To complete the family...为了完成家庭...

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

After all that, we can finally do something like this:毕竟,我们终于可以做这样的事情了:

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

Edit for Swift 4.2为 Swift 4.2 编辑

Starting in Swift 4.2, instead of using the imported C function arc4random_uniform(), you can now use Swift's own native functions.从 Swift 4.2 开始,您现在可以使用 Swift 自己的原生函数,而不是使用导入的 C 函数 arc4random_uniform()。

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

You can use random(in:) to get random values for other primitive values as well;您也可以使用random(in:)来获取其他原始值的随机值; such as Int, Double, Float and even Bool.例如 Int、Double、Float 甚至 Bool。

Swift versions < 4.2斯威夫特版本 < 4.2

This method will generate a random Int value between the given minimum and maximum此方法将在给定的最小值和最大值之间生成一个随机Int

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

我使用了这段代码:

var k: Int = random() % 10;

As of iOS 9, you can use the new GameplayKit classes to generate random numbers in a variety of ways.从 iOS 9 开始,您可以使用新的 GameplayKit 类以多种方式生成随机数。

You have four source types to choose from: a general random source (unnamed, down to the system to choose what it does), linear congruential, ARC4 and Mersenne Twister.您有四种源类型可供选择:一般随机源(未命名,由系统选择它的功能)、线性同余、ARC4 和 Mersenne Twister。 These can generate random ints, floats and bools.这些可以生成随机整数、浮点数和布尔值。

At the simplest level, you can generate a random number from the system's built-in random source like this:在最简单的层面上,您可以从系统的内置随机源生成一个随机数,如下所示:

GKRandomSource.sharedRandom().nextInt()

That generates a number between -2,147,483,648 and 2,147,483,647.这会生成一个介于 -2,147,483,648 和 2,147,483,647 之间的数字。 If you want a number between 0 and an upper bound (exclusive) you'd use this:如果你想要一个介于 0 和上限(不包括)之间的数字,你可以使用:

GKRandomSource.sharedRandom().nextIntWithUpperBound(6)

GameplayKit has some convenience constructors built in to work with dice. GameplayKit 内置了一些方便的构造函数来处理骰子。 For example, you can roll a six-sided die like this:例如,您可以像这样滚动一个六面骰子:

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

Plus you can shape the random distribution by using things like GKShuffledDistribution.另外,您可以使用 GKShuffledDistribution 之类的东西来塑造随机分布。 That takes a little more explaining, but if you're interested you can read my tutorial on GameplayKit random numbers .这需要更多解释,但如果您有兴趣,可以阅读我的 GameplayKit 随机数教程

You can do it the same way that you would in C:你可以像在 C 中那样做:

let randomNumber = arc4random()

randomNumber is inferred to be of type UInt32 (a 32-bit unsigned integer) randomNumber被推断为UInt32类型(一个 32 位无符号整数)

Use arc4random_uniform()使用arc4random_uniform()

Usage:用法:

arc4random_uniform(someNumber: UInt32) -> UInt32

This gives you random integers in the range 0 to someNumber - 1 .这为您提供了0someNumber - 1范围内的随机整数。

The maximum value for UInt32 is 4,294,967,295 (that is, 2^32 - 1 ). UInt32的最大值为 4,294,967,295(即2^32 - 1 )。

Examples:例子:

  • Coin flip硬币翻转

     let flip = arc4random_uniform(2) // 0 or 1
  • Dice roll掷骰子

     let roll = arc4random_uniform(6) + 1 // 1...6
  • Random day in October十月的随机一天

     let day = arc4random_uniform(31) + 1 // 1...31
  • Random year in the 1990s 1990年代的随机年份

     let year = 1990 + arc4random_uniform(10)

General form:一般形式:

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

where number , max , and min are UInt32 .其中numbermaxminUInt32

What about...关于什么...

arc4random() arc4random()

You can also get a random number by using arc4random() , which produces a UInt32 between 0 and 2^32-1.您还可以使用arc4random()获得一个随机数,它会产生一个介于 0 和 2^32-1 之间的UInt32 Thus to get a random number between 0 and x-1 , you can divide it by x and take the remainder.因此,要获得0x-1之间的随机数,您可以将其除以x并取余数。 Or in other words, use the Remainder Operator (%) :或者换句话说,使用余数运算符 (%)

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

However, this produces the slight modulo bias (see also here and here ), so that is why arc4random_uniform() is recommended.但是,这会产生轻微的模数偏差(另请参见此处此处),因此建议使用arc4random_uniform()

Converting to and from IntInt相互转换

Normally it would be fine to do something like this in order to convert back and forth between Int and UInt32 :通常可以这样做以便在IntUInt32之间来回转换:

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

The problem, though, is that Int has a range of -2,147,483,648...2,147,483,647 on 32 bit systems and a range of -9,223,372,036,854,775,808...9,223,372,036,854,775,807 on 64 bit systems.但是,问题在于Int在 32 位系统上的范围为-2,147,483,648...2,147,483,647 ,在 64 位系统上的范围为-9,223,372,036,854,775,808...9,223,372,036,854,775,807 Compare this to the UInt32 range of 0...4,294,967,295 .将此与0...4,294,967,295UInt32范围进行比较。 The U of UInt32 means unsigned . UInt32U表示unsigned

Consider the following errors:考虑以下错误:

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

So you just need to be sure that your input parameters are within the UInt32 range and that you don't need an output that is outside of that range either.因此,您只需要确保您的输入参数在UInt32范围内,并且您也不需要超出该范围的输出。

Example for random number in between 10 (0-9); 10 (0-9) 之间的随机数示例;

import UIKit

let randomNumber = Int(arc4random_uniform(10))

Very easy code - simple and short.非常简单的代码 - 简单而简短。

I've been able to just use rand() to get a random CInt.我已经能够使用rand()来获得一个随机的 CInt。 You can make it an Int by using something like this:您可以使用以下方法使其成为 Int :

let myVar: Int = Int(rand())

You can use your favourite C random function, and just convert to value to Int if needed.您可以使用您最喜欢的 C 随机函数,并在需要时将值转换为 Int。

@jstn's answer is good, but a bit verbose. @jstn 的回答很好,但有点冗长。 Swift is known as a protocol-oriented language, so we can achieve the same result without having to implement boilerplate code for every class in the integer family, by adding a default implementation for the protocol extension. Swift 被称为面向协议的语言,因此我们可以通过添加协议扩展的默认实现来实现相同的结果,而无需为整数系列中的每个类实现样板代码。

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

Now we can do:现在我们可以这样做:

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

and all other integer classes are ok.并且所有其他整数类都可以。

In Swift 4.2 you can generate random numbers by calling the random() method on whatever numeric type you want, providing the range you want to work with.Swift 4.2中,您可以通过对所需的任何数字类型调用random()方法来生成随机数,并提供您想要使用的范围。 For example, this generates a random number in the range 1 through 9, inclusive on both sides例如,这会生成 1 到 9 范围内的随机数,包括两边

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

Also with other types也与其他类型

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

Updated : June 09, 2022.更新日期:2022 年 6 月 9 日。

Swift 5.7斯威夫特 5.7

Let's assume we have an array:假设我们有一个数组:

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


For iOS and macOS you can use system-wide random source in Xcode's framework GameKit .对于 iOS 和 macOS,您可以在 Xcode 的框架GameKit中使用系统范围的随机源 Here you can find GKRandomSource class with its sharedRandom() class method:在这里您可以找到GKRandomSource类及其sharedRandom()类方法:

import GameKit

private func randomNumberGenerator() -> Int {
    let rand = GKRandomSource.sharedRandom().nextInt(upperBound: numbers.count)
    return numbers[rand]
}

randomNumberGenerator()


Also you can use a randomElement() method that returns a random element of a collection:您还可以使用randomElement()方法返回集合的随机元素:

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


Or use arc4random_uniform() .或使用arc4random_uniform() Pay attention that this method returns UInt32 type.注意这个方法返回UInt32类型。

let generator = Int(arc4random_uniform(11))
print(generator)


And, of course, we can use a makeIterator() method that returns an iterator over the elements of the collection.而且,当然,我们可以使用makeIterator()方法,该方法返回集合元素的迭代器。

let iterator: Int = (1...10).makeIterator().shuffled().first!
print(iterator)


The final example you see here returns a random value within the specified range with a help of static func random(in range: ClosedRange<Int>) -> Int .您在此处看到的最后一个示例在static func random(in range: ClosedRange<Int>) -> Int的帮助下返回指定范围内的随机值。

let randomizer = Int.random(in: 1...10)
print(randomizer)


Pseudo-random Double number generator drand48() returns a value between 0.0 and 1.0.伪随机双数生成器drand48()返回一个介于 0.0 和 1.0 之间的值。

import Foundation

let randomInt = Int(drand48() * 10)

Here is a library that does the job well https://github.com/thellimist/SwiftRandom这是一个做得很好的库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
    }
}

Since Swift 4.2Swift 4.2 开始

There is a new set of APIs:有一组新的 API:

let randomIntFrom0To10 = Int.random(in: 0 ..< 10)
let randomDouble = Double.random(in: 1 ... 10)
  • All numeric types now have the random(in:) method that takes range .所有数字类型现在都有接受rangerandom(in:)方法。

  • It returns a number uniformly distributed in that range.它返回一个均匀分布在该范围内的数字。


TL;DR TL;博士

Well, what is wrong with the "good" old way?那么,“好”的旧方法有什么问题?

  1. You have to use imported C APIs (They are different between platforms) .您必须使用导入的C API (它们在平台之间有所不同)

  2. And moreover...而且……

What if I told you that the random is not that random?如果我告诉你随机不是那么随机怎么办?

If you use arc4random() (to calculate the remainder) like arc4random() % aNumber , the result is not uniformly distributed between the 0 and aNumber .如果您使用arc4random() (计算余数) ,如arc4random() % aNumber ,则结果不会0aNumber之间均匀分布。 There is a problem called the Modulo bias .有一个叫做模偏差的问题。

Modulo bias模偏置

Normally, the function generates a random number between 0 and MAX (depends on the type etc.) .通常,该函数会生成一个介于0MAX之间的随机数(取决于类型等) To make a quick, easy example, let's say the max number is 7 and you care about a random number in the range 0 ..< 2 (or the interval [0, 3) if you prefer that) .举一个简单、快速的例子,假设最大数是7 ,并且您关心0 ..< 2 (或区间 [0, 3) 如果您愿意的话)范围内的随机数。

The probabilities for individual numbers are:个别数字的概率是:

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

In other words, you are more likely to end up with 0 or 1 than 2 .换句话说,你更有可能最终得到01而不是2 Of course, bare in mind that this is extremely simplified and the MAX number is much higher, making it more "fair".当然,请记住,这是非常简化的,并且MAX数字要高得多,使其更加“公平”。

This problem is addressed by SE-0202 - Random unification in Swift 4.2 SE-0202 - Swift 4.2中的随机统一解决了这个问题

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

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

Here 5 will make sure that the random number is generated through zero to four.这里 5 将确保从零到四生成随机数。 You can set the value accordingly.您可以相应地设置该值。

I would like to add to existing answers that the random number generator example in the Swift book is a Linear Congruence Generator (LCG), it is a severely limited one and shouldn't be except for the must trivial examples, where quality of randomness doesn't matter at all.我想在现有答案中补充一点,Swift 书中的随机数生成器示例是线性同余生成器(LCG),它是一个严重受限的示例,除了必须琐碎的示例之外不应如此,其中随机性的质量不一点都不重要。 And a LCG should never be used for cryptographic purposes .并且LCG 永远不应该用于加密目的

arc4random() is much better and can be used for most purposes, but again should not be used for cryptographic purposes. arc4random()要好得多,可以用于大多数目的,但同样不应用于加密目的。

If you want something that is guaranteed to be cryptographically secure, use SecCopyRandomBytes() .如果您想要保证加密安全的东西,请使用SecCopyRandomBytes() Note that if you build a random number generator into something, someone else might end up (mis)-using it for cryptographic purposes (such as password, key or salt generation), then you should consider using SecCopyRandomBytes() anyway, even if your need doesn't quite require that.请注意,如果您将随机数生成器构建到某个东西中,其他人可能最终(错误)将其用于加密目的(例如密码、密钥或盐生成),那么您应该考虑使用SecCopyRandomBytes()无论如何,即使您的需要并不完全需要。

Without arc4Random_uniform() in some versions of Xcode(in 7.1 it runs but doesn't autocomplete for me).在某些版本的 Xcode 中没有 arc4Random_uniform() (在 7.1 中它运行但不会自动完成)。 You can do this instead.您可以改为这样做。

To generate a random number from 0-5.生成一个 0-5 的随机数。 First第一的

import GameplayKit

Then然后

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

Swift 4.2斯威夫特 4.2

Bye bye to import Foundation C lib arc4random_uniform()再见,导入 Foundation 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. You use random(in:) to generate random digits from ranges.您使用 random(in:) 从范围中生成随机数字。
  2. randomElement() returns nil if the range is empty, so you unwrap the returned Int?如果范围为空,则 randomElement() 返回 nil,因此您解开返回的 Int? with if let.如果让。
  3. You use random(in:) to generate a random Double, Float or CGFloat and random() to return a random Bool.您使用 random(in:) 生成随机 Double、Float 或 CGFloat 并使用 random() 返回随机 Bool。

More @ Official 更多@官方

The following code will produce a secure random number between 0 and 255:以下代码将生成 0 到 255 之间的安全随机数:

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

You call it like this:你这样称呼它:

print(UInt8.random)

For bigger numbers it becomes more complicated.对于更大的数字,它变得更加复杂。
This is the best I could come up with:这是我能想到的最好的:

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

These methods use an extra random number to determine how many UInt8 s are going to be used to create the random number.这些方法使用一个额外的随机数来确定将使用多少UInt8来创建随机数。 The last line converts the [UInt8] to UInt16 or UInt32 .最后一行将[UInt8]转换为UInt16UInt32

I don't know if the last two still count as truly random, but you can tweak it to your likings :)我不知道最后两个是否仍然算作真正随机的,但您可以根据自己的喜好对其进行调整:)

Swift 4.2斯威夫特 4.2

Swift 4.2 has included a native and fairly full-featured random number API in the standard library. Swift 4.2 在标准库中包含了一个原生且功能相当全面的随机数 API。 ( Swift Evolution proposal SE-0202 ) Swift Evolution 提案 SE-0202

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

All number types have the static random(in:) which takes the range and returns the random number in the given range所有数字类型都有静态随机数(in:) ,它接受范围并返回给定范围内的随机数

Xcode 14, swift 5 Xcode 14, swift 5

public extension Array where Element == Int {
    static func generateNonRepeatedRandom(size: Int) -> [Int] {
        guard size > 0 else {
            return [Int]()
        }
        return Array(0..<size).shuffled()
    }
}

How to use:如何使用:

let array = Array.generateNonRepeatedRandom(size: 15)
print(array)

Output Output

在此处输入图像描述

You can use GeneratorOf like this:您可以像这样使用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())

I use this code to generate a random number:我使用此代码生成一个随机数:

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

Details细节

xCode 9.1, Swift 4 xCode 9.1,斯威夫特 4

Math oriented solution (1)面向数学的解决方案 (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
}

Usage of solution (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]

Programmers oriented solution (2)面向程序员的解决方案 (2)

Do not forget to add Math oriented solution (1) code here不要忘记在此处添加面向数学的解决方案 (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]
    }
}

Usage of solution (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]

Full Sample完整样本

Do not forget to add solution (1) and solution (2) codes here不要忘记在此处添加解决方案(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]
}

Sample result样本结果

在此处输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM