美文网首页
Swift 的一些拓展

Swift 的一些拓展

作者: jamalping | 来源:发表于2017-11-07 11:31 被阅读0次

前言:虽说Swift的Array、Dictionary相交于oc来说已经提供了更多方便快捷的api来提高我们开发的效率,比如Swift提供了map、filter、reduce、flatMap等高阶函数。但在实际开发过程中,这些高阶函数可能也不能完全满足我们的需求。那么,我就要拓展Array、Dictionary的api来增强他们的功能。

Array

  • 从Array中随机取出一个元素
var random: Element? {
        get {
            guard count > 0 else { return nil }
            let index = Int(arc4random_uniform(UInt32(count)))
            return self[index]
        }
    }

接下来的拓展要求Array的Element遵循Equatable协议,具体写法如下

extension Array where Element: Equatable {
    
    /// 判断数组中是否包含某个数组
    func containArray(_ array: [Element]) -> Bool {
        var flag: Bool = true
        array.forEach { (element) in
            if !self.contains(element) {
                flag = false
            }
        }
        return flag
    }
    
    
    /// 找出两个数组中不同的元素,并组成新的数组
    func difference(_ values: [Element]...) -> [Element] {
        var result = [Element]()
        
        elements: for element in self {
            for value in values {
                if value.contains(element) {
                    continue elements
                }
            }
            result.append(element)
        }
        return result
    }
    
    
    /// 找出两个数组中相同的元素,并组成新的数组
    public func intersection(_ values: [Element]...) -> [Element] {
        var result = self
        var intersection = Array()
        
        for (i, value) in values.enumerated() {
            //  the intersection is computed by intersecting a couple per loop:
            //  self n values[0], (self n values[0]) n values[1], ...
            if i > 0 {
                result = intersection
                intersection = Array()
            }
            
            //  find common elements and save them in first set
            //  to intersect in the next loop
            value.forEach { (item: Element) -> Void in
                if result.contains(item) {
                    intersection.append(item)
                }
            }
        }
        return intersection
    }
    
    /// 将数组中不存在的元素加进来
    public func union(_ values: [Element]...) -> [Element] {
        var result = self
        for array in values {
            for value in array {
                if !result.contains(value) {
                    result.append(value)
                }
            }
        }
        return result
    }
    
    /// 数组中相同的元素只保留一个
    public func unique() -> Array {
        return reduce([]) { $0.contains($1) ? $0 : $0 + [$1] }
    }
}

Dictionary

public extension Dictionary {
    
    /// 获取一个随机值
    func random() -> Value? {
        return Array(values).random
    }
    
    /// 是否存在该key
    func has(_ key: Key) -> Bool {
        return index(forKey: key) != nil
    }
    
    /// 将不存在的键值对加进来。已存在的进行值得更新
    public func union(_ dictionaries: Dictionary...) -> Dictionary {
        var result = self
        dictionaries.forEach { (dictionary) -> Void in
            dictionary.forEach { (key, value) -> Void in
                result[key] = value
            }
        }
        return result
    }
    
    /// 
    public func difference(_ dictionaries: [Key: Value]...) -> [Key: Value] {
        var result = self
        for dictionary in dictionaries {
            for (key, value) in dictionary {
                if result.has(key) && result[key] == value as! _OptionalNilComparisonType {
                    result.removeValue(forKey: key)
                }
            }
        }
        return result
    }
    
    /// 转换字典键值对的类型
    public func map<K, V>(_ map: (Key, Value) -> (K, V)) -> [K: V] {
        var mapped: [K: V] = [:]
        forEach {
            let (_key, _value) = map($0, $1)
            mapped[_key] = _value
        }
        return mapped
    }
    
    
    /// 将JSONString转换成Dictionary
    public static func constructFromJSON (json: String) -> Dictionary? {
        if let data = (try? JSONSerialization.jsonObject(
            with: json.data(using: String.Encoding.utf8,
                            allowLossyConversion: true)!,
            options: JSONSerialization.ReadingOptions.mutableContainers)) as? Dictionary {
            return data
        } else {
            return nil
        }
    }
    
    /// 转换成JSON
    func formatJSON() -> String? {
        if let jsonData = try? JSONSerialization.data(withJSONObject: self, options: JSONSerialization.WritingOptions()) {
            let jsonStr = String(data: jsonData, encoding: String.Encoding(rawValue: String.Encoding.utf8.rawValue))
            return String(jsonStr ?? "")
        }
        return nil
    }
}

UIColor

public extension UIColor {
    // user:UIColor.init(hexString: "#ff5a10") ||UIColor.init(hexString: "ff5a10")
    convenience init(hexString: String, alpha: CGFloat = 1) {
        var r, g, b, a: CGFloat
        a = alpha
        var hexColor: String = hexString.trimmingCharacters(in: .whitespacesAndNewlines).uppercased()
        
        // 存在#,则将#去掉
        if (hexColor.hasPrefix("#")) {
            let splitIndex = hexColor.index(after: hexColor.startIndex)
            hexColor = String(hexColor[splitIndex...])
        }
        if hexColor.characters.count == 8 {
            let scanner = Scanner(string: hexColor)
            
            var hexNumber: UInt64 = 0
            
            if scanner.scanHexInt64(&hexNumber) {
                r = CGFloat((hexNumber & 0xff000000) >> 24) / 255
                g = CGFloat((hexNumber & 0x00ff0000) >> 16) / 255
                b = CGFloat((hexNumber & 0x0000ff00) >> 8) / 255
                a = CGFloat(hexNumber & 0x000000ff) / 255
                
                self.init(red: r, green: g, blue: b, alpha: a)
                return
            }
        } else if hexColor.characters.count == 6 {
            let scanner = Scanner(string: hexColor)
            var hexNumber: UInt64 = 0
            
            if scanner.scanHexInt64(&hexNumber) {
                r = CGFloat((hexNumber & 0xff0000) >> 16) / 255
                g = CGFloat((hexNumber & 0x00ff00) >> 8) / 255
                b = CGFloat(hexNumber & 0x0000ff) / 255
                self.init(red: r, green: g, blue: b, alpha: a)
                return
            }
        }
        // 设置默认值
        self.init(white: 0.0, alpha: 1)
    }
    
    //用数值初始化颜色,便于生成设计图上标明的十六进制颜色
    //user: UIColor.init(valueHex: 0xff5a10)
    convenience init(valueHex: UInt, alpha: CGFloat = 1.0) {
        
        self.init(
            red: CGFloat((valueHex & 0xFF0000) >> 16) / 255.0,
            green: CGFloat((valueHex & 0x00FF00) >> 8) / 255.0,
            blue: CGFloat(valueHex & 0x0000FF) / 255.0,
            alpha: alpha
        )
    }
    
    /// 获取随机颜色
    /// - Returns: 随机颜色
    class func randamColor() -> UIColor{
        let R = CGFloat(arc4random_uniform(255))/255.0
        let G = CGFloat(arc4random_uniform(255))/255.0
        let B = CGFloat(arc4random_uniform(255))/255.0
        return UIColor.init(red: R, green: G, blue: B, alpha: 1)
    }
    
    /// 生产渐变颜色
    ///
    /// - Parameters:
    ///   - from: 开始的颜色
    ///   - toColor: 结束的颜色
    ///   - height: 渐变颜色的高度
    /// - Returns: 渐变颜色
    class func gradientColor(_ fromColor: UIColor, toColor: UIColor, height: CGFloat) -> UIColor? {
        let size = CGSize.init(width: 1, height: height)
        UIGraphicsBeginImageContextWithOptions(size, false, 0)
        let context = UIGraphicsGetCurrentContext()
        let colorSpace = CGColorSpaceCreateDeviceRGB()
        let colors = [fromColor.cgColor, toColor.cgColor]
        
        guard let gradient: CGGradient = CGGradient.init(colorsSpace: colorSpace, colors: colors as CFArray, locations: nil) else { return nil }
        
        context?.drawLinearGradient(gradient, start: CGPoint.init(x: 0, y: 0), end: CGPoint.init(x: 0, y: size.height), options: .drawsBeforeStartLocation)
        
        guard let image = UIGraphicsGetImageFromCurrentImageContext() else { return nil }
        
        UIGraphicsEndImageContext()
        
        return UIColor.init(patternImage: image)
    }
    
    /// 获取对应的rgba值
    var component: (CGFloat,CGFloat,CGFloat,CGFloat) {
        get {
            var r: CGFloat = 0
            var g: CGFloat = 0
            var b: CGFloat = 0
            var a: CGFloat = 0
            getRed(&r, green: &g, blue: &b, alpha: &a)
            return (r * 255,g * 255,b * 255,a)
        }
    }
}

String

public extension String {

    /// 长度
    var length: Int {
        return self.characters.count
    }

    /// 删除两端空格
    var trimmingSpace: String {
        return self.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines)
    }

    // 下标范围取值:eg: "12345"[1..<3] = "23"
    subscript (i : Range<Int>) -> String {
        get {
            let startIndex = self.index(self.startIndex, offsetBy: i.lowerBound)
            let endIndex = self.index(self.startIndex, offsetBy: i.upperBound)
            return String(self[startIndex ..< endIndex])
        }
    }
    
    /// 每隔一段插入一个字符
    ///
    /// - Parameters:
    ///   - string: 插入的字符串
    ///   - len: 每隔几位
    /// - Returns: 插入后的字符串
    func insert(string: String, len: Int) -> String {
        if self.length < 1 { return self }
        var resultString = ""
        var index = 0
        while  index < self.length {
            if index + len >= self.length {
                resultString += self[index..<self.length]
                break
            }
            let news = self[index..<index+len]
            resultString = resultString + news + string
            index += len
        }
        return resultString
    }
    
    /// 使用正则表达式替换
    ///
    /// - Parameters:
    ///   - pattern: 正则
    ///   - with: <#with description#>
    ///   - options: <#options description#>
    /// - Returns: <#return value description#>
    /// - eg:pregReplace(pattern: "[A-Z]", with: "_$0")  大写转小写,并前面添加一个_
    func regexReplace(pattern: String, with: String,
                      options: NSRegularExpression.Options = []) -> String {
        let regex = try! NSRegularExpression(pattern: pattern, options: options)
        return regex.stringByReplacingMatches(in: self, options: [],
                                              range: NSMakeRange(0, self.length),
                                              withTemplate: with)
    }
    
    /// 获取字符串子串
    ///
    /// - Parameter index: 切割的初始位置
    /// - Returns: 子串
    func subString(from index: Int) -> String {
        if index <= self.length {
            return String(self[index..<self.length])
        }
        return self
    }
    
    /// 获取字符串子串
    ///
    /// - Parameter index: 切割的最终位置
    /// - Returns: 子串
    func subString(to index: Int) -> String {
        if index <= self.length {
            return String(self[0..<index])
        }
        return self
    }
    
    /// 根据字符串生成Swift的类
    ///
    /// - Parameter string: 类名的字符串
    /// - Returns: Swift类
    static func swiftClassFromString(string: String) -> AnyClass? {

        let appName = Bundle.main.object(forInfoDictionaryKey: "CFBundleName") as! String
        let classStringName = "_TtC\(appName.characters.count)\(appName)"+"\(string.characters.count)"+string

        return NSClassFromString(classStringName)
    }
}

PS: 这里摘取了我写的工具类中的一部分列子,欢迎各位老铁查看github上的源码,有需要的也可以直接拿来用,使用pod 'XPUtil'。同时也非常乐意各位老铁补充。

相关文章

网友评论

      本文标题:Swift 的一些拓展

      本文链接:https://www.haomeiwen.com/subject/kbgdmxtx.html