Last active
November 22, 2020 17:57
-
-
Save username0x0a/4dcc11b0eeb57fa25ea5861a3d64786e to your computer and use it in GitHub Desktop.
Life-saving String extension for Swift >= 5.0 easing the split–filter–join flows.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Foundation | |
#if swift(>=5.0) | |
extension StringProtocol where Index == String.Index { | |
func split(string str: String) -> [Substring] { | |
var si = self.startIndex | |
let ei = self.endIndex | |
var ret = [Substring]() | |
if str == "" { | |
while si != ei { | |
let next = self.index(after: si) | |
if let ss = self[si..<next] as? Substring | |
{ | |
if (self.distance(from: self.startIndex, to: next) > 0) { | |
ret.append(ss) | |
} | |
} | |
si = next | |
} | |
} | |
repeat | |
{ | |
if let r = self.range(of: str, options: [], range: (si..<ei), locale: nil) { | |
if let ss = self[si..<r.lowerBound] as? Substring | |
{ | |
if (self.distance(from: self.startIndex, to: r.lowerBound) > 0) { | |
ret.append(ss) | |
} | |
} | |
si = r.upperBound | |
if si >= ei { break } | |
// if si > ei { break } // switch to include empty element at the end | |
} | |
else { | |
if let ss = self[si..<ei] as? Substring | |
{ | |
ret.append(ss) | |
} | |
break | |
} | |
} while true | |
return ret.filter { !$0.isEmpty } | |
} | |
} | |
extension Array where Element : StringProtocol { | |
func join(string str: String) -> String { | |
return self.joined(separator: str) | |
} | |
} | |
// Sample use | |
"máslo, sádlo, banány, lovec, kámen" | |
.split(string: ", ") | |
.filter { $0.contains("lo") } | |
.join(string: " ☢️ ") | |
// Tests & Ruby result equality | |
"".split(string: " ") | |
// ✅ [] | |
"a".split(string: " ") | |
// ✅ ["a"] | |
"a b c d".split(string: " ") | |
// ✅ ["a","b","c","d"] | |
" a b c d".split(string: " ") | |
// ✅ ["a","b","c","d"] | |
" a b c d".split(string: " ") | |
// ✅ ["a","b","c","d"] | |
"a b c d ".split(string: " ") | |
// ✅ ["a","b","c","d"] | |
"a b c d ".split(string: " ") | |
// ✅ ["a","b","c","d"] | |
" a b c d ".split(string: " ") | |
// ✅ ["a","b","c","d"] | |
"a b c d ".split(string: " o") | |
// ✅ ["a b c d "] | |
"abcd".split(string: "") | |
// ✅ ["a","b","c","d"] | |
" ".split(string: "") | |
// ✅ [" "," "," "," "," "," "," "," "," "," "] | |
"👀😁🙈😄".split(string: "") | |
// ✅ ["👀","😁","🙈","😄"] | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment