美文网首页
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