Last active
October 19, 2023 16:02
-
-
Save tatimagdalena/b2556d6deba5c400d4f2e46a095dadfc to your computer and use it in GitHub Desktop.
String extension to transform string into several case types
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 | |
| extension String { | |
| public var upperCasedFirstLetter: String { | |
| prefix(1).uppercased() + dropFirst() | |
| } | |
| public var lowerCasedFirstLetter: String { | |
| prefix(1).lowercased() + dropFirst() | |
| } | |
| public func lowerCamelCased() -> String { | |
| upperCamelCased().lowerCasedFirstLetter | |
| } | |
| public func upperCamelCased() -> String { | |
| let lowerCasedSelf = lowercased() | |
| let components = lowerCasedSelf.components(separatedBy: CharacterSet(charactersIn: " _-.")) | |
| return components.reduce("") { partialResult, word in | |
| partialResult + word.capitalized | |
| } | |
| } | |
| public func camelCaseToSnakeCase() -> String { | |
| let components = componentsSeparatedByUppercase() | |
| return components.map({$0.lowercased()}).joined(separator: "_") | |
| } | |
| public func camelCaseToDotCase() -> String { | |
| let components = componentsSeparatedByUppercase() | |
| return components.map({$0.lowercased()}).joined(separator: ".") | |
| } | |
| private func componentsSeparatedByUppercase() -> [String] { | |
| var components: [String] = [] | |
| var currentComponent = "" | |
| unicodeScalars.forEach { character in | |
| if currentComponent.isEmpty.not && character.caseType == CharacterCase.upper { | |
| components.append(currentComponent) | |
| currentComponent = character.escaped(asASCII: false) | |
| } else { | |
| currentComponent += character.escaped(asASCII: false) | |
| } | |
| } | |
| components.append(currentComponent) | |
| return components | |
| } | |
| } | |
| private enum CharacterCase { | |
| case lower | |
| case upper | |
| case none | |
| } | |
| extension UnicodeScalar { | |
| fileprivate var caseType: CharacterCase { | |
| if CharacterSet.lowercaseLetters.contains(self) { .lower } | |
| else if CharacterSet.uppercaseLetters.contains(self) { .upper } | |
| else { .none } | |
| } | |
| } | |
| extension Bool { | |
| fileprivate var not: Bool { !self } | |
| } | |
| // MARK: - Tests - | |
| // TODO: Move to a Test target | |
| @testable import MyApp | |
| import XCTest | |
| final class StringCaseTransformTests: XCTestCase { | |
| func testLowerCamelCased() { | |
| let snakecaseString = "This_iS-a_string" | |
| let lowerCamelCased = snakecaseString.lowerCamelCased() | |
| XCTAssertEqual(lowerCamelCased, "thisIsAString") | |
| } | |
| func testUpperCamelCased() { | |
| let snakecaseString = "This_iS-a_string" | |
| let upperCamelCased = snakecaseString.upperCamelCased() | |
| XCTAssertEqual(upperCamelCased, "ThisIsAString") | |
| } | |
| func testCamelCaseToSnakeCase() { | |
| let camelcaseString = "thisIsAString" | |
| let snakecaseString = camelcaseString.camelCaseToSnakeCase() | |
| XCTAssertEqual(snakecaseString, "this_is_a_string") | |
| } | |
| func testCamelCaseToDotCase() { | |
| let camelcaseString = "thisIsAString" | |
| let dotcaseString = camelcaseString.camelCaseToDotCase() | |
| XCTAssertEqual(dotcaseString, "this.is.a.string") | |
| } | |
| } | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment