String may not be indexed with 'Int' Swift3 - swift

i'm trying to display the first letter of my contact name in uppercase:
var firstLetter: String? = !(contact?.firstName == "") ? (contact?.firstName as? String)?.substring(to: 1).uppercased() : (contact?.lastName as? String)?.substring(to: 1).uppercased()
but i have got this error:
String may not be indexed with 'Int', it has variable size elements

Try this:
if let contact = contact
{
var firstLetter = !contact.firstName.isEmpty ? contact?.firstName.characters.first?.description.uppercased() : contact?.lastName.characters.first?.description.uppercased()
}
I will be able to help you more if you tell the type/definition of "contact".

Try this function to get first letter in capital format. Before the call check if your string is empty then don't call as you are doing in your code
func capitalizeFirst() -> String {
let firstIndex = self.index(startIndex, offsetBy: 1)
return self.substring(to: firstIndex).capitalized + self.substring(from: firstIndex).lowercased()
}

If you just need to find the first character, you can use contact?.uppercased().characters.first.
In general, to get the n-th character in uppercase, use contact?.uppercased()[contact?.index(contact?.startIndex, offsetBy: n)]

To avoid the long chain of indirections and make the function a bit clearer you could also write it like this :
firstLetter = ( (contact?.firstName ?? "") + (contact?.lastName ?? "") )
.characters.first?.description.uppercased()

var firstLetter = (contact?.firstName.characters.first ?? contact?.lastName.characters.first)?.description.uppercased()

Related

How to replace last 3 characters in Swift?

I'm trying to replace last three characters with "*", but I do not think I'm doing it okay.
I'll share my code below :
//This is the string and is looking like this : 07123456789
var phoneNumber = viewModel.securityAndLoginAssetsData?.userProfile.phones.phoneLogin
let endIndex = phoneNumber!.index(phoneNumber!.startIndex, offsetBy: -3)
var finalPhoneNumber = phoneNumber!.replaceSubrange(...endIndex, with: "*")
This is how I'm trying to display it, but I got this error :
"Type '()' cannot conform to 'StringProtocol'"
Text(finalPhoneNumber)
What can I do in this case, thanks :)
Try and avoid indices and force unwrapping:
extension String {
func replacing(last n: Int, with s: String) -> String {
let replacement = String(repeating: s, count: min(count, n))
return dropLast(n) + replacement
}
}
"123456".replacing(last: 3, with: "*") // 123***
The error is pretty self explanatory. finalPhoneNumber is not a String it is a method. This happens because replaceSubrange doesn’t return anything. It is a mutating method. What you need is to pass phoneNumber instead. Note that you have some other issues in your code like unwrapping phoneNumber and offset should be from endIndex. I would also pass starIndex as the limitedBy parameter or use formIndex to mutate endIndex var which doesnt return an optional and won't pass beyond startIndex when offsetting. Something like:
if var phoneNumber = viewModel.securityAndLoginAssetsData?.userProfile.phones.phoneLogin {
var endIndex = phoneNumber.endIndex
phoneNumber.formIndex(&endIndex, offsetBy: -3, limitedBy: phoneNumber.startIndex)
phoneNumber.replaceSubrange(endIndex..., with: repeatElement("*", count: min(3, phoneNumber.count)))
}

Format String left of multiple characters in Swift 5?

I have some Strings that vary in length but always end in "listing(number)"
myString = 9AMnep8MAziUCK7VwKF51mXZ2listing28
.
I want to get the String without "listing(number)":
9AMnep8MAziUCK7VwKF51mXZ2
.
Methods I've tried such as .index(of: ) only let you format based off one character. Any simple solutions?
A possible solution is to search for the substring with Regular Expression and remove the result (replace it with empty string)
let myString = "9AMnep8MAziUCK7VwKF51mXZ2listing28"
let trimmedString = myString.replacingOccurrences(of: "listing\\d+$", with: "", options: .regularExpression)
\\d+ searches for one ore more digits
$ represents the end of the string
Alternatively without creating a new string
var myString = "9AMnep8MAziUCK7VwKF51mXZ2listing28"
if let range = myString.range(of: "listing\\d+$", options: .regularExpression) {
myString.removeSubrange(range)
}
Another option is to split the string in parts with "listing" as separator
let result = myString.components(separatedBy: "listing").first
So to solve your issue find the code below with few comments written to try and explain each steps have taken. kindly note i have modified or arrived at this solution using this links as a guide.
https://stackoverflow.com/a/40070835/6596443
https://www.dotnetperls.com/substring-swift
extension String {
//
// Paramter inputString: This is the string you want to manipulate
// Paramter- startStringOfUnwanted: This is the string you want to start the removal or replacement from
//return : The expected output you want but can be emptystring if unable to
static func trimUnWantedEndingString(inputString: String,startStringOfUnwanted: String) -> String{
//Output string
var outputString: String?
//Getting the range based on the string content
if let range = myString.range(of: startStringOfUnwanted) {
//Get the lowerbound of the range
let lower = range.lowerBound
//Get the upperbound of the range
let upper = range.upperBound
//Get the integer position of the start index of the unwanted string i added plus one to ensure it starts from the right position
let startPos = Int(myString.distance(from: myString.startIndex, to: lower))+1
//Get the integer position of the end index of the unwanted string i added plus one to ensure it starts from the right position
let endPos = Int(myString.distance(from: myString.startIndex, to: upper))+1
//Substract the start int from the end int to get the integer value that will be used to get the last string i want to stop trimming at
let endOffsetBy = endPos-startPos
//get thes string char ranges of values
let result = myString.index(myString.startIndex, offsetBy: 0)..<myString.index(myString.endIndex, offsetBy: -endOffsetBy)
//converts the results to string or get the string representation of the result and then assign it to the OutputString
outputString = String(myString[result]);
}
return outputString ?? "";
}
}
let myString = "9AMnep8MAziUCK7VwKF51mXZ2listing28"
String.trimUnWantedEndingString(inputString: myString, startStringOfUnwanted:"listing")

String basics with Swift

Just trying to remove the first character from a string in Swift. I use the code written below, but the second line keeps crashing my application.
Is this not the correct way to unwrap a String Index? What is?
var tempText = text
let toRemove = tempText?.startIndex ?? String.Index(0)
tempText?.remove(at: toRemove)
You can use Collection method dropFirst:
if let text = text { // you need also to unwrap your optional
let tempText = String(text.characters.dropFirst()) // And initialize a new String with your CharacterView
}
In Swift 4 String conforms to Collection so you can use it directly on your string:
if let text = text {
let tempText = text.dropFirst() // "bc"
}
You are initializing a String.Index type instead of getting the index of the tempText string.
Moreover, startIndex is not an optional, tempText, however, is.
You should check if tempText exists and is not empty (you can simply do this with an if let), and remove the character at startIndex if it matches those conditions.
var tempText = text
if let toRemove = tempText?.startIndex {
tempText?.remove(at: toRemove)
}
If you are using swift 4, you can use:
var tempText = text.dropFirst()

Remove the first six characters from a String (Swift)

What's the best way to go about removing the first six characters of a string? Through Stack Overflow, I've found a couple of ways that were supposed to be solutions but I noticed an error with them. For instance,
extension String {
func removing(charactersOf string: String) -> String {
let characterSet = CharacterSet(charactersIn: string)
let components = self.components(separatedBy: characterSet)
return components.joined(separator: "")
}
If I type in a website like https://www.example.com, and store it as a variable named website, then type in the following
website.removing(charactersOf: "https://")
it removes the https:// portion but it also removes all h's, all t's, :'s, etc. from the text.
How can I just delete the first characters?
In Swift 4 it is really simple, just use dropFirst(n: Int)
let myString = "Hello World"
myString.dropFirst(6)
//World
In your case: website.dropFirst(6)
Why not :
let stripped = String(website.characters.dropFirst(6))
Seems more concise and straightforward to me.
(it won't work with multi-char emojis either mind you)
[EDIT] Swift 4 made this even shorter:
let stripped = String(website.dropFirst(6))
length is the number of characters you want to remove (6 in your case)
extension String {
func toLengthOf(length:Int) -> String {
if length <= 0 {
return self
} else if let to = self.index(self.startIndex, offsetBy: length, limitedBy: self.endIndex) {
return self.substring(from: to)
} else {
return ""
}
}
}
It will remove first 6 characters from a string
var str = "Hello-World"
let range1 = str.characters.index(str.startIndex, offsetBy: 6)..<str.endIndex
str = str[range1]
print("the end time is : \(str)")

String convert to Int and replace comma to Plus sign

Using Swift, I'm trying to take a list of numbers input in a text view in an app and create a sum of this list by extracting each number for a grade calculator. Also the amount of values put in by the user changes each time. An example is shown below:
String of: 98,99,97,96...
Trying to get: 98+99+97+96...
Please Help!
Thanks
Use components(separatedBy:) to break up the comma-separated string.
Use trimmingCharacters(in:) to remove spaces before and after each element
Use Int() to convert each element into an integer.
Use compactMap (previously called flatMap) to remove any items that couldn't be converted to Int.
Use reduce to sum up the array of Int.
let input = " 98 ,99 , 97, 96 "
let values = input.components(separatedBy: ",").compactMap { Int($0.trimmingCharacters(in: .whitespaces)) }
let sum = values.reduce(0, +)
print(sum) // 390
For Swift 3 and Swift 4.
Simple way: Hard coded. Only useful if you know the exact amount of integers coming up, wanting to get calculated and printed/used further on.
let string98: String = "98"
let string99: String = "99"
let string100: String = "100"
let string101: String = "101"
let int98: Int = Int(string98)!
let int99: Int = Int(string99)!
let int100: Int = Int(string100)!
let int101: Int = Int(string101)!
// optional chaining (if or guard) instead of "!" recommended. therefore option b is better
let finalInt: Int = int98 + int99 + int100 + int101
print(finalInt) // prints Optional(398) (optional)
Fancy way as a function: Generic way. Here you can put as many strings in as you need in the end. You could, for example, gather all the strings first and then use the array to have them calculated.
func getCalculatedIntegerFrom(strings: [String]) -> Int {
var result = Int()
for element in strings {
guard let int = Int(element) else {
break // or return nil
// break instead of return, returns Integer of all
// the values it was able to turn into Integer
// so even if there is a String f.e. "123S", it would
// still return an Integer instead of nil
// if you want to use return, you have to set "-> Int?" as optional
}
result = result + int
}
return result
}
let arrayOfStrings = ["98", "99", "100", "101"]
let result = getCalculatedIntegerFrom(strings: arrayOfStrings)
print(result) // prints 398 (non-optional)
let myString = "556"
let myInt = Int(myString)