From 641977704cf11c182f76c14e12b995eb875f31e7 Mon Sep 17 00:00:00 2001 From: Sami Samhuri Date: Sun, 20 Dec 2015 19:14:54 -0800 Subject: [PATCH] add more extensions --- Sources/CollectionType.swift | 70 +++++++++++++++++++++++++++++++ Sources/Files.swift | 2 + Sources/NSRegularExpression.swift | 14 +++++++ Sources/String.swift | 20 +++++++++ 4 files changed, 106 insertions(+) create mode 100644 Sources/CollectionType.swift create mode 100644 Sources/Files.swift create mode 100644 Sources/NSRegularExpression.swift diff --git a/Sources/CollectionType.swift b/Sources/CollectionType.swift new file mode 100644 index 0000000..a4ee30a --- /dev/null +++ b/Sources/CollectionType.swift @@ -0,0 +1,70 @@ +import Foundation + +#if os(Linux) + import Glibc +#else + import Darwin +#endif + +public extension CollectionType { + + /// Returns elements of the collection that match the given regular expression. + /// If elements are String or NSString instances they will be matched directly. + /// if they are NSObject instances their -description is matched. Otherwise + /// they are not matched. + func grep(regex: String) throws -> [Self.Generator.Element] { + let re = try NSRegularExpression(pattern: regex, options: NSRegularExpressionOptions(rawValue: 0)) + return filter({ item -> Bool in + if let string = item as? String { + return re.matches(string) + } + if let string = item as? NSString { + return re.matches(String(string)) + } + if let object = item as? NSObject { + return re.matches(object.description) + } + return false + }) + } + +} + +/// Returns a random integer between 1 and max +func randomInt(max: Int) -> Int { + #if os(Linux) + let n = random() % max + #else + let n = arc4random_uniform(UInt32(max)) + #endif + return 1 + Int(n) +} + +public extension CollectionType where Self.Index: Strideable { + + /// Returns a random element, or nil if the collection is empty + func sample() -> Generator.Element? { + guard count > 0 else { + return nil + } + let max = Int(count.toIntMax()) + let n = randomInt(max) - 1 + return self[startIndex.advancedBy(n)] + } + +} + +public extension CollectionType where Self.Generator.Element: Equatable { + + /// Returns the unique elements of a sorted collection by collapsing runs of + /// identical elements. + func unique() -> [Self.Generator.Element] { + var last: Self.Generator.Element? + return filter({ item -> Bool in + let isUnique: Bool = last == nil || last != item + last = item + return isUnique + }) + } + +} diff --git a/Sources/Files.swift b/Sources/Files.swift new file mode 100644 index 0000000..fbf2875 --- /dev/null +++ b/Sources/Files.swift @@ -0,0 +1,2 @@ +import Foundation + diff --git a/Sources/NSRegularExpression.swift b/Sources/NSRegularExpression.swift new file mode 100644 index 0000000..22cd34c --- /dev/null +++ b/Sources/NSRegularExpression.swift @@ -0,0 +1,14 @@ +import Foundation + +public extension NSRegularExpression { + + func match(string: String) -> [NSTextCheckingResult] { + let range = NSRange(location: 0, length: string.characters.count) + return self.matchesInString(string, options: NSMatchingOptions(rawValue: 0), range: range) + } + + func matches(string: String) -> Bool { + return self.match(string).count > 0 + } + +} diff --git a/Sources/String.swift b/Sources/String.swift index 5270a62..9ec2e4d 100644 --- a/Sources/String.swift +++ b/Sources/String.swift @@ -2,10 +2,30 @@ import Foundation public extension String { + // Check if this string contains the given string. func contains(substring: String) -> Bool { return rangeOfString(substring) != nil } + // Check if this string matches the given regular expression. + func matches(regex: String) -> Bool { + return rangeOfString(regex, options:.RegularExpressionSearch) != nil + } + + // Match the given regular expression against this string and return all + // the results. + func match(regex: String) throws -> [NSTextCheckingResult] { + let re = try NSRegularExpression(pattern: regex, options: NSRegularExpressionOptions(rawValue: 0)) + return re.match(self) + } + + func substringWithNSRange(range: NSRange) -> String { + let start = startIndex.advancedBy(range.location) + let end = start.advancedBy(range.length) + return substringWithRange(Range(start:start, end:end)) + } + + // Trim whitespace and newlines from the beginning and end of this string. func trim() -> String { return stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet()) }