Swift-使用泛型范围获取数组或区间中随机元素

实际开发中,通常会遇到获取一个随机数

  • 随机产生一个数字
  • 随机获取数组中的一个元素
  • 随机获取一种颜色

简单介绍:

一、最简单操作:给定一个最大值,随机获取一个0到最大值之间的数字

let int = arc4random_uniform(100) 

二、从一个范围中返回一个随机数

不足:此方法只支持返回一个半开区间 (x..

// 使用 upperBound 和 lowerBound需要导入改头文件
import Darwin

func randomNumber(from range: Range<Int>) -> Int {
   let distance = range.upperBound - range.lowerBound
   let rnd = arc4random_uniform(UInt32(distance))
   return range.lowerBound + Int(rnd)
}

可以使用一个半开的区间调用这个函数

let random1 = randomNumber(from: 1..<10)

但是不能传入一个闭合的区间:

let random2 = randomNumber(from: 1...9) // error

三、随机获取字符数组中的一个元素,数组内元素必须是字符串

func randomStringFromArray(from array: Array<Any>) -> String {
   let index: Int = Int(arc4random_uniform(UInt32(array.count)))
   return array[index] as! String
}

从一个字符数组中随机获取一个元素

let array = ["Mazy","Lucy","Lily","Vivian","Owen"]
let element = randomStringFromArray(from: array)

四、利用泛型随机获取数组中的一个元素,数组内可以是任意元素

func randomElementFromArray<T>(from array: Array<T>) -> T {
   let index: Int = Int(arc4random_uniform(UInt32(array.count)))
   return array[index] 
}

从数组中随机返回元素

// 字符串数组
let array = ["Mazy","Lucy","Lily","Vivian","Owen"]
let element = randomElementFromArray(from: array)

// 数字数组
let array1 = [1,5,8,32,7,88,6]        
let num = randomElementFromArray(from: array1)

五、思考:有没有一个方法,传入区间或数组,返回一个随机元素?

通过识别基本接口编写通用代码
参考于霍曼·梅尔:How to be DRY on ranges and closed ranges?

当我们尝试从随机函数中筛选出基本接口,即所需实现的最小功能集合:

  • 它需要一种有效的方法来计算输入序列的下限和上限之间的距离。
  • 它需要一种有效的方式来检索输入序列的第 n 个元素以便将其返回,其中 n 是从其长度的下界计算得到的随机距离。

霍曼注意到两个可计数的区间类型都遵守协议 RandomAccessCollection ,共享该公共协议的一致性。事实上,RandomAccessCollection 提供了我们想要的基本接口:可随机访问的集合保证了所需开销时间都是恒定的,而这些开销主要集中在测量索引间距离以及访问任意索引所指向的元素。

因此,把 random 函数定义成 RandomAccessCollection 中的方法

// MARK: - 随机函数筛选元素
extension RandomAccessCollection {
    func random() -> Iterator.Element? {
        guard count > 0 else {
            return nil
        }
        let offset = arc4random_uniform(numericCast(count))
        let i = index(startIndex, offsetBy: numericCast(offset))
        return self[i]
    }
}

随机函数的使用

// 获取区间的中随机数
let a = (50...100).random() // 闭区间
let b = (0..<9).random()  // 开区间

let array = ["Mazy","Lucy","Lily","Vivian","Owen"]
let name = array.random()

六、随机函数的高级使用

结合随机函数,给 UIColor 添加 extension 获取一个随机颜色
extension UIColor {
    static var randomColor: UIColor {
        get {
            let r: CGFloat = CGFloat((0...255).random()!)/255.0
            let g: CGFloat = CGFloat((0...255).random()!)/255.0
            let b: CGFloat = CGFloat((0...255).random()!)/255.0
            // 或者使用一下原生函数获取随机数
            /*
            let redValue   = CGFloat(Int(arc4random() % 255)) / 255.0
            let blueValue  = CGFloat(Int(arc4random() % 255)) / 255.0
            let greenValue = CGFloat(Int(arc4random() % 255)) / 255.0
            */
            return UIColor(red: r, green: g, blue: b, alpha: 1.0)
        }
    }
}

获取随机颜色

let color = UIColor.randomColor
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值