How to check the string doesn’t contain any letters in swift? - swift

i have trouble during making the letter checker, my code is like this: if !containLetters(“1234h”){print(“pass”)}
my function is
func containsOnlyNum(input: String) -> Bool {
var ok = false
for chr in input {
for check in "1234567890.-"{
if chr == check{
ok = true
}
}
if ok != true{
return false
}
}
return true
}
If I check for “h” then didn’t pass, but if i check for ”1h” then it still pass! Please help me to fix this problem. I will give a big thank for anyone who helped me

The simplest way to fix the algorithm is this way:
func containsOnlyNum(input: String) -> Bool {
// check every character
for chr in input {
var isNum = false
for check in "1234567890.-"{
if chr == check {
isNum = true
// if we have found a valid one, we can break the iteration
break
}
}
if !isNum {
return false
}
}
return true
}
print(containsOnlyNum(input: "1234")) // true
print(containsOnlyNum(input: "1234h")) // false
However, then you can directly simplify it to:
func containsOnlyNum(input: String) -> Bool {
return input.allSatisfy { chr in
"1234567890.-".contains(chr)
}
}
which does exatly the same but uses allSatisfy and contains functions, which represent the logical operators ALL and EXISTS.
However, programmers normally use regular expressions for similar tasks:
func containsOnlyNum(input: String) -> Bool {
return input.range(of: "^[0-9.\\-]+$", options: .regularExpression) != nil
}

You can check that a string contains only the characters you're interested in like this:
extension String {
var containsOnlyNum: Bool {
let wanted = CharacterSet.decimalDigits
.union(CharacterSet(charactersIn: "-."))
return unicodeScalars
.allSatisfy(wanted.contains)
}
}
"-12.34".containsOnlyNum // true
"A1234".containsOnlyNum // false
But if you are interested in numbers, then this is a problem:
"-12.-34.".containsOnlyNum // true
Instead, you can just try casting the string to a double and see if it is a number or not
Double("1234") != nil // true, a number
Double("-1.234") != nil // true, a number
Double("A1234") != nil // false, not a number
Double("-12.-34.") != nil // false, not a number
Which is almost right unless you don't want this case:
Double("1234e2") != nil // true, a number
But you can use both checks if you don't want to allow that, or else if you are able to parse a Double from the input you can just do the cast.

Related

How do I solve 'No exact matches in call to initializer'?

func hasUniqueDigits(number: String) -> Bool {
var numbers = [1, 2, 3, 4, 5, 6, 7]
for i in 1...6 {
var partOne = number.firstIndex(of: String.Element("\(i)"))
var partTwo = String(numbers.firstIndex(of: Int(partOne))!)
numbers.remove(at: partTwo)
}
if numbers.count == 1 {
return true
} else {
return false
This is a function for determining whether a six-digit number containing only the digits 1-7 contains all unique digits.
Examples: 145327 works, 114723 doesn't because it has two ones, and 183427 doesn't because it contains an 8.
I have typed in random !'s to see if it was an optional problem and that didn't work. Can you please let me know hot to fix this error?
Not a direct answer to your question but it would be much easier to use sets. To check if the string have duplicated digits all you need is to check if the string count is the same of the character set count. To check if the string has only the allowed digits you can simply check if the number character set is a subset of the numbers character set:
func hasUniqueDigits(number: String) -> Bool {
let set1 = Set(number)
if number.count != set1.count { return false }
return set1.isStrictSubset(of: Set("1234567"))
}
hasUniqueDigits(number: "145327") // true
hasUniqueDigits(number: "114723") // false
hasUniqueDigits(number: "183427") // false
Note that this would return true for an empty string as well. If you want to make sure this method returns false just add a check to return false if number is empty:
if number.count != set1.count || number.isEmpty { return false }

How to check if a string contains multiple characters in Swift 5

I have a failure initializer that takes a string, if this string contains incorrect characters (T, A, C, G) I want to return nil:
I tried something like this, unsuccessful:
init?(strand: String) {
let success = strand.contains(where: { !"TACG".contains($0) })
if !success {
return nil
}
self.strand = strand
}
I somehow got confused by the two contains calls, so I am not sure if my check is correct.
Any help is appreciated.
In this case I'd prefer the API rangeOfCharacter(from which checks the string against a character set
init?(strand: String) {
guard strand.rangeOfCharacter(from: CharacterSet(charactersIn: "TACG")) == nil else { return nil }
self.strand = strand
}
If you don't want to import Foundation you can also use Collection method allSatisfy
func allSatisfy(_ predicate: (Character) throws -> Bool) rethrows -> Bool
And make sure your string contains all characters
let allSatisfy = "CGAT".allSatisfy("TACG".contains)
print(allSatisfy) // true
Just move the ! placement, check out the code below .
init?(strand: String) {
let success = !strand.contains(where: { "TACG".contains($0) })
if !success {
return nil
}
self.strand = strand
}

Swift Bool Function return will never executed

I want to create a code which can determine whether the character is one of the symbols in my list.
var symbols = ["+","-"]
func issymbol(last:String ) -> Bool{
return true
for i in 0...(symbols.count){
if last == symbols[i]{
return false
}
}
}
You need to add return true at the end and it will execute if last == symbols[i]{ never met. So update your code as shown below:
func issymbol(last:String) -> Bool{
for i in 0...(symbols.count){
if last == symbols[i]{
return false
}
}
return true
}
issymbol(last: "+") //false
Or you can use contains property for that:
func issymbol(last:String) -> Bool{
return !symbols.contains(last)
}
issymbol(last: "+") // false
issymbol(last: "1") // true
No code execute after return keyword. so I update your code try this
var symbols = ["+","-"]
func issymbol(last:String ) -> Bool{
for value in symbols {
if last == value {
return true
}
}
return false
}
Functions only execute until they reach a return statement. Xcode detected that the rest of the code in that function won't be executed, because your function will always return after the first line. You probably meant something like this:
var symbols = ["+","-"]
func issymbol(last:String ) -> Bool{
for i in 0...(symbols.count){
if last == symbols[i]{
return false
}
}
return true
}
Because the return statement is after the for loop, the for loop can execute. This function will return true if the string you pass in is not in the symbols array.
There are a lot issues in this code.
The line return true returns immediately so the check won't be performed (the error message).
The line for i in 0...(symbols.count) will crash because the index starts at 0 and the last index is symbols.count - 1. Alternatively you can write for i in 0..<symbols.count.
The best syntax is not to write an index based loop:
for symbol in symbols { if last == symbol ...
If the item is found the code returns false rather than true.
The code doesn't return a Bool after the loop if the item was not found (will cause another error).
The correct code is
let symbols = ["+","-"]
func issymbol(last: String) -> Bool {
for i in 0...symbols.count - 1 {
if last == symbols[i] {
return true
}
}
return false
}
However this can be reduced to
func issymbol(last: String) -> Bool {
return symbols.contains(last)
}

Setting variable equal to if statement condition

I have an if statement that checks to see if an array element matches a local variable.
if pinArray.contains(where: {$0.title == restaurantName})
How would I create a variable of this element?
I attempted
let thePin = pinArray.contains(where: {$0.title == restaurantName})
but this comes with "could not cast boolean to MKAnnotation".
I also tried variations of
let pins = [pinArray.indexPath.row]
let pinn = pins(where: pin.title == restaurantName) (or close to it)
mapp.selectAnnotation(thePin as! MKAnnotation, animated: true)
to no avail. What basic step am I missing?
contains(where:) returns a Bool indicating whether a match was found or not. It does not return the matched value.
So thePin is a Bool which you then attempt to force-cast to a MKAnnotation which of course crashes.
If you want the matching value, change your code to:
if let thePin = pinArray.first(where: { $0.title == restaurantName }) {
do {
mapp.selectionAnnotation(thePin, animated: true)
} catch {
}
} else {
// no match in the array
}
No need for contains at all. No need to cast (assuming pinArray is an array of MKAnnotation).

Check empty string in Swift?

In Objective C, one could do the following to check for strings:
if ([myString isEqualToString:#""]) {
NSLog(#"myString IS empty!");
} else {
NSLog(#"myString IS NOT empty, it is: %#", myString);
}
How does one detect empty strings in Swift?
There is now the built in ability to detect empty string with .isEmpty:
if emptyString.isEmpty {
print("Nothing to see here")
}
Apple Pre-release documentation: "Strings and Characters".
A concise way to check if the string is nil or empty would be:
var myString: String? = nil
if (myString ?? "").isEmpty {
print("String is nil or empty")
}
I am completely rewriting my answer (again). This time it is because I have become a fan of the guard statement and early return. It makes for much cleaner code.
Non-Optional String
Check for zero length.
let myString: String = ""
if myString.isEmpty {
print("String is empty.")
return // or break, continue, throw
}
// myString is not empty (if this point is reached)
print(myString)
If the if statement passes, then you can safely use the string knowing that it isn't empty. If it is empty then the function will return early and nothing after it matters.
Optional String
Check for nil or zero length.
let myOptionalString: String? = nil
guard let myString = myOptionalString, !myString.isEmpty else {
print("String is nil or empty.")
return // or break, continue, throw
}
// myString is neither nil nor empty (if this point is reached)
print(myString)
This unwraps the optional and checks that it isn't empty at the same time. After passing the guard statement, you can safely use your unwrapped nonempty string.
In Xcode 11.3 swift 5.2 and later
Use
var isEmpty: Bool { get }
Example
let lang = "Swift 5"
if lang.isEmpty {
print("Empty string")
}
If you want to ignore white spaces
if lang.trimmingCharacters(in: .whitespaces).isEmpty {
print("Empty string")
}
Here is how I check if string is blank. By 'blank' I mean a string that is either empty or contains only space/newline characters.
struct MyString {
static func blank(text: String) -> Bool {
let trimmed = text.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines)
return trimmed.isEmpty
}
}
How to use:
MyString.blank(" ") // true
You can also use an optional extension so you don't have to worry about unwrapping or using == true:
extension String {
var isBlank: Bool {
return self.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty
}
}
extension Optional where Wrapped == String {
var isBlank: Bool {
if let unwrapped = self {
return unwrapped.isBlank
} else {
return true
}
}
}
Note: when calling this on an optional, make sure not to use ? or else it will still require unwrapping.
To do the nil check and length simultaneously
Swift 2.0 and iOS 9 onwards you could use
if(yourString?.characters.count > 0){}
isEmpty will do as you think it will, if string == "", it'll return true.
Some of the other answers point to a situation where you have an optional string.
PLEASE use Optional Chaining!!!!
If the string is not nil, isEmpty will be used, otherwise it will not.
Below, the optionalString will NOT be set because the string is nil
let optionalString: String? = nil
if optionalString?.isEmpty == true {
optionalString = "Lorem ipsum dolor sit amet"
}
Obviously you wouldn't use the above code. The gains come from JSON parsing or other such situations where you either have a value or not. This guarantees code will be run if there is a value.
Check check for only spaces and newlines characters in text
extension String
{
var isBlank:Bool {
return self.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet()).isEmpty
}
}
using
if text.isBlank
{
//text is blank do smth
}
Swift String (isEmpty vs count)
You should use .isEmpty instead of .count
.isEmpty Complexity = O(1)
.count Complexity = O(n)
isEmpty does not use .count under the hood, it compares start and end indexes startIndex == endIndex
Official doc Collection.count
Complexity: O(1) if the collection conforms to RandomAccessCollection; otherwise, O(n), where n is the length of the collection.
Single character can be represented by many combinations of Unicode scalar values(different memory footprint), that is why to calculate count we should iterate all Unicode scalar values
String = alex
String = \u{61}\u{6c}\u{65}\u{78}
[Char] = [a, l, e, x]
Unicode text = alex
Unicode scalar values(UTF-32) = u+00000061u+0000006cu+00000065u+00000078
1 Character == 1 extended grapheme cluster == set of Unicode scalar values
Example
//Char á == extended grapheme cluster of Unicode scalar values \u{E1}
//Char á == extended grapheme cluster of Unicode scalar values \u{61}\u{301}
let a1: String = "\u{E1}" // Unicode text = á, UTF-16 = \u00e1, UTF-32 = u+000000e1
print("count:\(a1.count)") //count:1
// Unicode text = a, UTF-16 = \u0061, UTF-32 = u+00000061
// Unicode text = ́, UTF-16 = \u0301, UTF-32 = u+00000301
let a2: String = "\u{61}\u{301}" // Unicode text = á, UTF-16 = \u0061\u0301, UTF-32 = u+00000061u+00000301
print("count:\(a2.count)") //count:1
For optional Strings how about:
if let string = string where !string.isEmpty
{
print(string)
}
if myString?.startIndex != myString?.endIndex {}
I can recommend add small extension to String or Array that looks like
extension Collection {
public var isNotEmpty: Bool {
return !self.isEmpty
}
}
With it you can write code that is easier to read.
Compare this two lines
if !someObject.someParam.someSubParam.someString.isEmpty {}
and
if someObject.someParam.someSubParam.someString.isNotEmpty {}
It is easy to miss ! sign in the beginning of fist line.
public extension Swift.Optional {
func nonEmptyValue<T>(fallback: T) -> T {
if let stringValue = self as? String, stringValue.isEmpty {
return fallback
}
if let value = self as? T {
return value
} else {
return fallback
}
}
}
What about
if let notEmptyString = optionalString where !notEmptyString.isEmpty {
// do something with emptyString
NSLog("Non-empty string is %#", notEmptyString)
} else {
// empty or nil string
NSLog("Empty or nil string")
}
You can use this extension:
extension String {
static func isNilOrEmpty(string: String?) -> Bool {
guard let value = string else { return true }
return value.trimmingCharacters(in: .whitespaces).isEmpty
}
}
and then use it like this:
let isMyStringEmptyOrNil = String.isNilOrEmpty(string: myString)