Skip to content

Instantly share code, notes, and snippets.

@tatimagdalena
Last active June 19, 2023 12:35
Show Gist options
  • Save tatimagdalena/1279076397002d6bde381bdc639cf2df to your computer and use it in GitHub Desktop.
Save tatimagdalena/1279076397002d6bde381bdc639cf2df to your computer and use it in GitHub Desktop.
// MARK: Optional
public extension Optional where Wrapped == String {
var orEmpty: String { self ?? "" }
var isNilOrEmpty: Bool {
orEmpty.isEmpty
}
var isNotNilNorEmpty: Bool {
!isNilOrEmpty
}
}
// MARK: Queries
public extension String {
var isBlank: Bool {
trimmingCharacters(in: .whitespaces).isEmpty
}
var isNotBlank: Bool {
!isBlank
}
var isNotEmpty: Bool {
!isEmpty
}
var isNumber: Bool {
!isEmpty && rangeOfCharacter(from: CharacterSet.decimalDigits.inverted) == nil
}
func doesNotContain(_ element: Character) -> Bool {
!contains(element)
}
func countOccurrences(of string: String) -> Int {
components(separatedBy: string).count - 1
}
}
// MARK: Sanitizers
public extension String {
var decimalsOnly: String {
removingCharacters(in: CharacterSet.decimalDigits.inverted)
}
var extraSpacesRemoved: String {
trimmingCharacters(in: .whitespacesAndNewlines)
}
var nonAlphanumericsRemoved: String {
let alphanumericCharacters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
let resultChars: [Character] = compactMap {
let unnaccentedChar = String($0).unnaccented
return alphanumericCharacters.contains(unnaccentedChar) ? $0 : nil
}
return String(resultChars)
}
var unnaccented: String {
folding(options: .diacriticInsensitive, locale: .current)
}
func truncate(_ length: Int, trailing: String = "…") -> String {
(count > length) ? prefix(length) + trailing : self
}
func removingCharacters(in characterSet: CharacterSet) -> String {
components(separatedBy: characterSet).joined()
}
func removingCharacters(in characterSets: CharacterSet...) -> String {
var result = self
for set in characterSets {
result = result.removingCharacters(in: set)
}
return result
}
func replacingNonAlphanumerics(with replacingChar: Character) -> String {
let alphanumericCharacters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
let resultChars: [Character] = map {
let unnaccentedChar = String($0).unnaccented
return alphanumericCharacters.contains(unnaccentedChar) ? $0 : replacingChar
}
return String(resultChars)
}
/// Escape special characters in HTML, namely &"<>
func escapeHTML() -> String {
var finalString = ""
for char in self {
for scalar in String(char).unicodeScalars {
finalString.append("&#\(scalar.value)")
}
}
return finalString
}
func paddingLeft(toLength newLength: Int, withPad padString: String) -> String {
let toPad = newLength - count
if toPad < 1 { return self }
return "".padding(toLength: toPad, withPad: padString, startingAt: 0) + self
}
var initials: String {
let textComponents = components(separatedBy: " ")
return (textComponents.count == 1 ? [textComponents.first] : [textComponents.first, textComponents.last])
.compactMap { $0?.first }
.map(String.init)
.joined()
}
subscript (i: Int) -> Character { self[index(startIndex, offsetBy: i)] }
var digits: String { filter { $0.isWholeNumber } }
var decimal: Decimal { Decimal(string: digits) ?? 0
}
// MARK: Data
extension String {
var data: Data { self.data(using: .utf8) ?? Data() }
}
// MARK: String Protocol
public extension StringProtocol {
/// Formats the string similarly to `.capitalized` method, but capitalizes only
/// the first letter of the string.
///
/// Example:
///
/// "LOREM IPSUM DOLOR SIT AMET".firstUppercased
/// "Lorem Ipsum Dolor Sit Amet".firstUppercased
/// "LoReM IpSuM DoLoR SiT AmEt".firstUppercased
/// // all return "Lorem ipsum dolor sit amet"
///
var firstUppercased: String {
lowercased().prefix(1).uppercased() + dropFirst().lowercased()
}
}
// MARK: Transformations
extension String {
/// It converts an string `U+1F434` into an unicode emoji
var asUnicodeEmoji: String? {
if
let emojiCode = split(separator: "+").last,
let emojiHexCode = Int(String(emojiCode), radix: 16),
let emoji = Unicode.Scalar(emojiHexCode)
{
return String(emoji)
}
return nil
}
func separate(every stride: Int = 4, with separator: Character = " ") -> String {
String(enumerated().map { $0 > 0 && $0.isMultiple(of: stride) ? [separator, $1] : [$1] }.joined())
}
func fallbackIfEmpty(to fallbackText: String) -> String {
isEmpty ? fallbackText : self
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment