Is a String part of another String in Swift - ios

I programmed a Search Bar in Swift. Now I need to check if the searched Word is part of a Word in my Array
Example :
Search: hel - word in array: hello --> true
Search: bs - word in array: hello --> false
And is there a way to check that I only get true when the Search is the beginning of the Word in my Array --
Example:
Search: hel - word in array: hello --> true
Search: lo - word in array: hello --> false
Sorry for my bad english :D

This code will do exactly what you want, I assumed that you ensure that the input and the word form your array is a valid string. Using startIndex and endIndex is recommended to get proper glyph counting in a String in Swift and you can easily refer to a part of a string by using brackets:
var input = "hel"
let wordInArray = "hello"
if wordInArray[input.startIndex..<input.endIndex] == input {
println(true)
} else {
println(false)
}
this will evaluate to true when the input is "hel" and gives false in case of "lo"
(depending from your spec, you must check if the length of the search input is less or equal to the word in the Array or use min(input.endIndex,wordInArray.endIndex) at the max value of the range to prevent error)

In Objective-C there was a function for finding locations of characters in NSStrings. rangeOfString:. In swift, from what I've found, it's
var range = text.rangeOfString("your-string");
if(range.startIndex == 0)
//This was found at the very beginning of the text string
Work with that code a bit and you will be able to find the location of the found string inside the searched string.

Related

Understanding function with string validation

Consider following:
extension String {
func isValidEmail() -> Bool {
let characterset = CharacterSet(charactersIn: "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
print(characterset)
if self.rangeOfCharacter(from: characterset.inverted) != nil {
return false
} else {
return true
}
}
}
var name = "Login"
name.isValidEmail() // print true
var incorretLogin = "Loginъ"
incorretLogin.isValidEmail() // print false
Yes, function is work. But im in confussion - how its work?
If i understand correct it work like that:
it take set of characters, then check if all of tested string characters contain symbols from set, and if it is not, then it return false.
Ok, but what is inverted for? If i remove inverted, result will be wrong:
var name = "Login"
name.isValidEmail() // false
var incorretLogin = "Logъin"
incorretLogin.isValidEmail() // false
Now i understand nothing.
If function check simply if string letters are from character set, then why is it matter if set inverted or not?
Could someone explain?
I play a bit in playground:
let characterset = CharacterSet(charactersIn: "a")
print(characterset)
print(characterset.inverted)
Print same result:
<CFCharacterSet Items(U+0061)>
<CFCharacterSet Items(U+0061)>
inverted "returns an inverted copy of the receiver." (see https://developer.apple.com/documentation/foundation/characterset).
In your case inverted means all the characters except the ones you provide in the initializer (all characters except letters and digits). So the method returns false if the email string contains any character that is not a letter or a digit.
Playground example:
According to the documentation
rangeOfCharacter(from:)
Finds and returns the range in the receiver of the first character from a given character set.
The receiver is the string being checked. When no character from the set is found in the string, nil is returned.
When the set is inverted, it contains all invalid characters. Hence, rangeOfCharacter(from:) returns the location of the first invalid character. That is why your first approach works.
When you remove inverted, the call returns the location of the first valid character. Since "Logъin" has both valid and invalid characters, both calls return false. If you call your second function on a string consisting entirely of invalid characters, e.g. "Логин", you would get true.
Note that you can simplify the implementation by removing if:
let characterset = CharacterSet(charactersIn: "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
return self.rangeOfCharacter(from: characterset.inverted) == nil

How to use split and map method?

I saw a question: Swift: Split a String into an array
And there's some code I don't understand:
let fullName = "First Last"
let fullNameArr = split(fullName.characters){$0 == " "}.map{String($0)}
fullNameArr[0] // First
fullNameArr[1] // Last
How does split() and map{} work?
You're using a syntax that won't work in Xcode7. The correct syntax should be
let fullNameArr = fullName.characters.split{$0 == " "}.map(String.init)
Getting that out of the way let's break down that line into two pieces:
split takes
A collection of Characters representing the String's extended
grapheme clusters
-- From Xcode docs
and a closure taking a character and returning Bool - true if the character can be considered as a separator.
if this syntax is confusing try reading that:
fullNameArr = fullName.characters.split({
character in
return character == " "
})
Now, split returns an array of SubSequence objects. You want to convert them back to string to be able to print them nicely. So one way of doing it would be creating a for loop iterating over all the results of split and converting them to string, then appending to a result array, or using map method that does the same.
If you look closely at the first line, you execute map on the array and pass a closure that does something with every element of the array and writes it back.
A simple example how that works
let exampleArray = [1, 2, 3]
print(exampleArray.map {$0 * 3})
// prints [3, 6, 9]
Hope that helps!

How to capitalize each word in a string using Swift iOS

Is there a function to capitalize each word in a string or is this a manual process?
For e.g. "bob is tall"
And I would like "Bob Is Tall"
Surely there is something and none of the Swift IOS answers I have found seemed to cover this.
Are you looking for capitalizedString
Discussion
A string with the first character in each word changed to its corresponding uppercase value, and all remaining characters set to their corresponding lowercase values.
and/or capitalizedStringWithLocale(_:)
Returns a capitalized representation of the receiver using the specified locale.
For strings presented to users, pass the current locale ([NSLocale currentLocale]). To use the system locale, pass nil.
Swift 3:
var lowercased = "hello there"
var stringCapitalized = lowercased.capitalized
//prints: "Hello There"
Since iOS 9 a localised capitalization function is available as capitalised letters may differ in languages.
if #available(iOS 9.0, *) {
"istanbul".localizedCapitalizedString
// In Turkish: "İstanbul"
}
An example of the answer provided above.
var sentenceToCap = "this is a sentence."
println(sentenceToCap.capitalizedStringWithLocale(NSLocale.currentLocale()) )
End result is a string "This Is A Sentence"
For Swift 3 it has been changed to capitalized .
Discussion
This property performs the canonical (non-localized) mapping. It is suitable for programming operations that require stable results not depending on the current locale.
A capitalized string is a string with the first character in each word changed to its corresponding uppercase value, and all remaining characters set to their corresponding lowercase values. A “word” is any sequence of characters delimited by spaces, tabs, or line terminators (listed under getLineStart(_:end:contentsEnd:for:)). Some common word delimiting punctuation isn’t considered, so this property may not generally produce the desired results for multiword strings.
Case transformations aren’t guaranteed to be symmetrical or to produce strings of the same lengths as the originals. See lowercased for an example.
There is a built in function for that
nameOfString.capitalizedString
This will capitalize every word of string. To capitalize only the first letter you can use:
nameOfString.replaceRange(nameOfString.startIndex...nameOfString.startIndex, with: String(nameOfString[nameOfString.startIndex]).capitalizedString)
Older Thread
Here is what I came up with that seems to work but I am open to anything that is better.
func firstCharacterUpperCase(sentenceToCap:String) -> String {
//break it into an array by delimiting the sentence using a space
var breakupSentence = sentenceToCap.componentsSeparatedByString(" ")
var newSentence = ""
//Loop the array and concatinate the capitalized word into a variable.
for wordInSentence in breakupSentence {
newSentence = "\(newSentence) \(wordInSentence.capitalizedString)"
}
// send it back up.
return newSentence
}
or if I want to use this as an extension of the string class.
extension String {
var capitalizeEachWord:String {
//break it into an array by delimiting the sentence using a space
var breakupSentence = self.componentsSeparatedByString(" ")
var newSentence = ""
//Loop the array and concatinate the capitalized word into a variable.
for wordInSentence in breakupSentence {
newSentence = "\(newSentence) \(wordInSentence.capitalizedString)"
}
// send it back up.
return newSentence
}
}
Again, anything better is welcome.
Swift 5 version of Christopher Wade's answer
let str = "my string"
let result = str.capitalized(with: NSLocale.current)
print(result) // prints My String

Check if string is already a currency string?

I would like to create a function that looks at a string, and if it's a decimal string, returns it as a currency-formatted string. The function below does that, however if I pass in a string that is already formatted, it will fail of course (it expects to see a string like '25' or '25.55' but not '$15.25'
Is there a way to modify my function below to add another if condition that says "if you've already been formatted as a currency string, or your string is not in the right format, return X" (maybe X will be 0, or maybe it will be self (the same string) i'm not sure yet).
func toCurrencyStringFromDecimalString() -> String
{
var numberFormatter = NSNumberFormatter()
numberFormatter.numberStyle = NSNumberFormatterStyle.CurrencyStyle
if (self.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceCharacterSet()).utf16Count == 0)
{
//If whitespace is passed in, just return 0.0 as default
return numberFormatter.stringFromNumber(NSDecimalNumber(string: "0.0"))!
}
else if (IS_NOT_A_DECIMAL_OR_ALREADY_A_CURRENCY_STRING)
{
//So obviously this would go here to see if it's not a decimal (or already contains a current placeholder etc)
}
else
{
return numberFormatter.stringFromNumber(NSDecimalNumber(string: self))!
}
}
Thank you for your help!
Sounds like you need to use NSScanner.
According to the docs, the scanDecimal function of NSScanner:
Skips past excess digits in the case of overflow, so the receiver’s
position is past the entire integer representation.
Invoke this method with NULL as value to simply scan past a decimal integer representation.
I've been mostly programming in Obj-C so my Swift is rubbish, but here's my attempt at translating the appropriate code for detecting numeric strings (as also demonstrated in this answer):
let scanner: NSScanner = NSScanner(string:self)
let isNumeric = scanner.scanDecimal(nil) && scanner.atEnd
If the string is not a decimal representation, isNumeric should return false.

How can I convert a string to a char array in ActionScript 3?

How do you convert a string into a char array in ActionScript 3.0?
I tried the below code but I get an error:
var temp:ByteArray = new ByteArray();
temp = input.toCharArray();
From the error, I understand that the toCharArray() function cannot be applied to a string (i.e in my case - input). Please help me out. I am a beginner.
I am not sure if this helps your purpose but you can use String#split():
If you use an empty string ("") as a delimiter, each character in the string is placed as an element in the array.
var array:Array = "split".split("");
Now you can get individual elements using index
array[0] == 's' ; array[1] == 'p' ....
Depending on what you need to do with it, the individual characters can also be accessed with string.charAt(index), without splitting them into an array.

Resources