前言:虽说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'
。同时也非常乐意各位老铁补充。
网友评论