Is there any way to tell Swift to check if a string ends with a symbol.
for example how can I write the code below in swift?
var string = "myString*"
if string ends with "*" {
.... do something
}
You can use the hasSuffix function.
let string = "Hello world!"
if string.hasSuffix("!") {
// do something
}
String has a method hasSuffix()
var string = "myString*"
if string.hasSuffix("*") {
.... do something
}
Related
I have a huge text in String.
For example "... value=word. ...". How can I get the string "word" if I know that before I have "value=" and after "."?
for example:
for str in string {
if str == "value=" {
// then get the strings until .
}
}
Thanks!
You can extend String with a kind of sliceBetween method:
import Foundation
extension String {
func sliceFrom(start: String, to: String) -> String? {
guard let s = rangeOfString(start)?.endIndex else { return nil }
guard let e = rangeOfString(to, range: s..<endIndex)?.startIndex else { return nil }
return self[s..<e]
}
}
And you'd use it like this:
"... value=word. ...".sliceFrom("value=", to: ". ") // "word"
NSRegularExpression should solve your issue.
In order to use it, you will need to understand Regex first. In your case, you can use value=[\\w]+[^.]+ as your regex pattern.
The following code will give you a [String] object contains value=allCharacterBeforeFirstPeriod
let regex = try NSRegularExpression(pattern: "value=[\\w]+[^.]+", options: [])
let nsStr = str as NSString
let array = regex.matchesInString(str, options: [], range: NSMakeRange(0, nsStr.length))
let results = array.map({ nsStr.substringWithRange($0.range) })
And then if you only need the value after value=, you can use another map function to do it:
results.map({ $0.stringByReplacingOccurrencesOfString("value=", withString: "") })
I have tested the code with a 10,000 characters String. It finishes in ~0.3 sec
The most straight forward way to do this would be to use NSRegularExpression. Tutorial
Given an input String like this
let text = "key0=value0&key1=value1&key2=value2"
You can organireduce method
let dict = text.characters.split("&").reduce([String:String]()) { (var result, keyValue) -> [String:String] in
let chunks = keyValue.split("=")
guard let first = chunks.first, last = chunks.last else { return result }
let key = String(first)
let value = String(last)
result[key] = value
return result
}
Now everything is stored inside dict and you can easily access it
dict["key2"] // "value2"
let str = "tHIS is A test"
let swapped_case = "This IS a TEST"
Swift noob here, how to do the second statement programatically?
This function works with all upper/lowercase characters
defined in Unicode, even those from "foreign" languages such as Ä or ć:
func swapCases(_ str : String) -> String {
var result = ""
for c in str.characters { // Swift 1: for c in str {
let s = String(c)
let lo = s.lowercased() //Swift 1 & 2: s.lowercaseString
let up = s.uppercased() //Swift 1 & 2: s.uppercaseString
result += (s == lo) ? up : lo
}
return result
}
Example:
let str = "tHIS is a test ÄöÜ ĂćŒ Α" // The last character is a capital Greek Alpha
let swapped_case = swapCases(str)
print(swapped_case)
// This IS A TEST äÖü ăĆœ α
Use switch statement in-range checks to determine letter case, and use NSString-bridged methods to convert accordingly.
let str = "tHIS is A test"
let swapped_case = "This IS a TEST"
func swapCase(string: String) -> String {
var swappedCaseString: String = ""
for character in string {
switch character {
case "a"..."z":
let uppercaseCharacter = (String(character) as NSString).uppercaseString
swappedCaseString += uppercaseCharacter
case "A"..."Z":
let lowercaseCharacter = (String(character) as NSString).lowercaseString
swappedCaseString += lowercaseCharacter
default:
swappedCaseString += String(character)
}
}
return swappedCaseString
}
swapCase(str)
I'm a bit too late but this works too :-)
let str = "tHIS is A test"
var res = ""
for c in str {
if contains("ABCDEFGHIJKLMNOPQRSTUVWXYZ", c) {
res += "\(c)".lowercaseString
} else {
res += "\(c)".uppercaseString
}
}
res
In Swift 5 I achieved it by creating a function which iterates through each character of the string, and using string methods to change each character I appended each character back into a new variable:
func reverseCase(string: String) -> String {
var newCase = ""
for char in string {
if char.isLowercase {
newCase.append(char.uppercased())
}
else if char.isUppercase {
newCase.append(char.lowercased())
}
else {
newCase.append(char)
}
}
return newCase
}
Then just pass your string through to the function when you call it in a print statement:
print(reverseCase(string: str))
You already have plenty of good succinct answers but here’s an over-elaborate one for fun.
Really this is a job for map – iterate over a collection (in this case String) and do a thing to each element (here, each Character). Except map takes any collection, but only gives you back an array, which you’d have to then turn into a String again.
But here’s a version of map that, given an extensible collection, gives you back that same kind of extensible collection.
(It does have the limitation of needing both collections to contain the same type, but that’s fine for strings. You could make it return a different type, but then you’d have to tell it which type you wanted i.e. map(s, transform) as String which would be annoying)
func map<C: ExtensibleCollectionType>(source: C, transform: (C.Generator.Element) -> C.Generator.Element) -> C {
var result = C()
for elem in source {
result.append(transform(elem))
}
return result
}
Then to write the transform function, first here’s an extension to character similar to the other answers. It does seem quite unsatisfying that you have to convert to a string just to uppercase a character, is there really no good (international characterset-friendly) way to do this?
extension Character {
var uppercaseCharacter: Character {
let s = String(self).uppercaseString
return s[s.startIndex]
}
var lowercaseCharacter: Character {
let s = String(self).lowercaseString
return s[s.startIndex]
}
}
And the function to flip the case. What I wonder is whether this pattern matching is international-friendly. It seems to be – "A"..."Z" ~= "Ä" returns true.
func flipCase(c: Character) -> Character {
switch c {
case "A"..."Z":
return c.lowercaseCharacter
case "a"..."z":
return c.uppercaseCharacter
default:
return c
}
}
Finally:
let s = map("Hello", flipCase)
// s is a String = "hELLO"
I hope this helps. inputString and resultString are the input and output respectively.
let inputString = "Example"
let outputString = inputString.characters.map { (character) -> Character in
let string = String(character)
let lower = string.lowercased()
let upper = string.uppercased()
return (string == lower) ? Character(upper) : Character(lower)
}
let resultString = String(outputString)
Is there any existing function that looks for the index of a substring inside another string? A method like .indexOfSubstring thank does this:
let word: String = "Hey there, how are you?"
let indexOf: Int = word.indexOfSubstring("ere, how are")
println("index = " + \(indexOf))
and prints:
index = 6
You can use the rangeOfString method:
import Foundation
let word: String = "Hey there, how are you?"
if let range = word.rangeOfString("ere, how are") {
let index = distance(word.startIndex, range.startIndex)
println("index = \(index)")
}
It returns a range, i.e. both sides of the searched string - just use the startIndex property.
Note that this is a method borrowed from NSString
There is no build in method in Swift. You will need to implement it yourself. Another implementation of this is
/// Get the start index of string
///
/// :return start index of .None if not found
public func indexOf(str: String) -> Int? {
return self.indexOfRegex(Regex.escapeStr(str))
}
/// Get the start index of regex pattern
///
/// :return start index of .None if not found
public func indexOfRegex(pattern: String) -> Int? {
if let range = Regex(pattern).rangeOfFirstMatch(self).toRange() {
return range.startIndex
}
return .None
}
This code is from this library which has bunch of extensions for common swift types such as String
https://github.com/ankurp/Dollar.swift/blob/master/Cent/Cent/String.swift#L62
You can checkout the docs on the usage
http://www.dollarswift.org/#indexof-str-string-int
I have the same problem like in this question:
How do I check if a string contains another string in Swift?
But now a few months later I wonder if it can be done without using NSString?
I nice and simple contains-method would be fine.
I searched the web and the documentation but I found nothing!
Same way, just with Swift syntax:
let string = "This is a test. This is only a test"
if string.rangeOfString("only") != nil {
println("yes")
}
For Swift 3.0
if str.range(of: "abc") != nil{
print("Got the string")
}
String actually provides a "contains" function through StringProtocol.
No extension whatsoever needed:
let str = "asdf"
print(str.contains("sd") ? "yep" : "nope")
https://developer.apple.com/reference/swift/string
https://developer.apple.com/documentation/swift/stringprotocol
If you want to check if your string matches a specific pattern, I can recommend the NSHipster article about NSRegularExpressions: http://nshipster.com/nsregularexpression/
I wrote an extension on String for SWIFT 3.0 so that i could simply call absoluteString.contains(string: "/kredit/")
extension String {
public func contains(string: String)-> Bool {
return self.rangeOfString(string) != nil
}
}
just to demonstrate the use of options.
var string = "This is a test. This is only a test. Not an Exam"
if string.range(of:"ex") != nil {
print("yes")
}
if string.range(of:"ex", options: String.CompareOptions.caseInsensitive) != nil {
print("yes")
}
I have a library which has a function like this:
int get_user_name(const char **buffer);
in swift, should call like this:
var name:CMutablePointer<CString> = nil
get_user_name(name)
I want make use this function more comfortable so I wrapped this up:
func get_username() -> String {
var name:CMutablePointer<CString> = nil
get_user_name(name)
// how to convert name to String
}
I question is how to convert name to String
It goes something like:
var stringValue :CString = ""
name.withUnsafePointer {p in
stringValue = p.memory
}
return NSString(CString: stringValue)
You can do:
return NSString(UTF8String: name[0])