import Dispatch import Foundation extension Array where Element: NSTextCheckingResult { func ranges() -> [NSRange] { return map { $0.range } } } extension Array where Element: Equatable { var unique: [Element] { var uniqueValues = [Element]() for item in self where !uniqueValues.contains(item) { uniqueValues.append(item) } return uniqueValues } } extension Array { static func array(of obj: Any?) -> [Element]? { if let array = obj as? [Element] { return array } else if let obj = obj as? Element { return [obj] } return nil } func group(by transform: (Element) -> U) -> [U: [Element]] { return Dictionary(grouping: self, by: { transform($0) }) } func partitioned(by belongsInSecondPartition: (Element) throws -> Bool) rethrows -> (first: ArraySlice, second: ArraySlice) { var copy = self let pivot = try copy.partition(by: belongsInSecondPartition) return (copy[0..(transform: (Element) -> [T]) -> [T] { return parallelMap(transform: transform).flatMap { $0 } } func parallelCompactMap(transform: (Element) -> T?) -> [T] { return parallelMap(transform: transform).compactMap { $0 } } func parallelMap(transform: (Element) -> T) -> [T] { var result = ContiguousArray(repeating: nil, count: count) return result.withUnsafeMutableBufferPointer { buffer in DispatchQueue.concurrentPerform(iterations: buffer.count) { idx in buffer[idx] = transform(self[idx]) } return buffer.map { $0! } } } } extension Collection { var isNotEmpty: Bool { return !isEmpty } }