Swift, Reverse only letters [closed] - ios

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 months ago.
Improve this question
I face the problem. When i try to reverse only letters in swift by using Two pointer pattern its actually doing swap instead.
sample - Test 123 String
2 pointer output - gnir 123 tStseT
expected output - tseT 123 gnirtS
Can somebody advice the method, or give example of code pls.?
func reverseOnlyLetters(_ S: String) -> String {
var a = Array(S.unicodeScalars)
var i = 0
var j = a.count - 1
while i < j {
while !CharacterSet.letters.contains(a[i]) && i < j { i += 1 }
while !CharacterSet.letters.contains(a[j]) && i < j { j -= 1 }
let t = a[i]
a[i] = a[j]
a[j] = t
i += 1
j -= 1
}
var ret = ""
a.forEach({ ret += String(Character(UnicodeScalar($0))) })
return ret
}

try this:
func reverseOnlyLetters(_ S: String) -> String {
let components = S.components(separatedBy: " ")
let reversedComponents = components.map { Int($0) == nil ? String($0.reversed()) : $0 }
return reversedComponents.joined(separator: " ")
}
if it still not correct, please give me more infomation

Related

How to replace a word in a string if it contains any words from an array [duplicate]

This question already has answers here:
Replace multiple words from a String based on the values in an Array
(4 answers)
Closed 3 years ago.
I'd like to find and replace any word(s) in a string that match any string value in an array. I can find the matching value using .contains(where:
var playersApprovedArray = ["Monica","Zach","Chrissy"]
card.cardText = "Chrissy, do 10 jumping jacks right now!"
if playersApprovedArray.contains(where: card.cardText.contains) {
print("Found matching player in card text")
// Replace the matching word/player here with another word/player
}
But I don't know how to replace the occurrence of the matching word with another string value in the array.
Here is a simple solution that replaces one player with another:
for i in playersApprovedArray.indices {
let player = playersApprovedArray[i]
if let range = cardText.range(of: player) {
let otherIndex = (i + Int.random(in: 1..<playersApprovedArray.count)) % playersApprovedArray.count
let otherPlayer = playersApprovedArray[otherIndex]
cardText.replaceSubrange(range, with: otherPlayer)
break
}
}
You can remove the break if the sentence may contains more players.
Here is a faster solution that would replace all occurrences of any player's name by another:
let playersApprovedArray = ["Monica","Zach","Chrissy"]
let cardText = " Chrissy, do 10 jumping jacks right now! "
var result = ""
var i = cardText.startIndex
while i < cardText.endIndex {
var j = i
while j < cardText.endIndex,
CharacterSet.letters.inverted.isSuperset(of: CharacterSet(charactersIn: String(cardText[j])))
{
j = cardText.index(after: j)
}
var tempo1 = ""
if i != j { tempo1 += cardText[i..<j] }
if j < cardText.endIndex { i = j } else {
result += tempo1
break
}
while j < cardText.endIndex,
CharacterSet.letters.isSuperset(of: CharacterSet(charactersIn: String(cardText[j])))
{
j = cardText.index(after: j)
}
let tempo2 = String(cardText[i..<j])
if let index = playersApprovedArray.firstIndex(of: tempo2) {
let otherIndex = (index + Int.random(in: 1..<playersApprovedArray.count)) % playersApprovedArray.count
let otherPlayer = playersApprovedArray[otherIndex]
result += tempo1 + otherPlayer
//See comment below for possible early exit
} else {
result += tempo1 + tempo2
}
i = j
}
print(result) // Monica, do 10 jumping jacks right now!
If you're sure that there is only one player in the string, then you can exit early this way:
...
result += tempo1 + otherPlayer + cardText[j...]
break
...

How many alphabets and numbers special characters in textfield [duplicate]

I want to count the number of letters, digits and special characters in the following string:
let phrase = "The final score was 32-31!"
I tried:
for tempChar in phrase {
if (tempChar >= "a" && tempChar <= "z") {
letterCounter++
}
// etc.
but I'm getting errors. I tried all sorts of other variations on this - still getting error - such as:
could not find an overload for '<=' that accepts the supplied arguments
For Swift 5 see rustylepord's answer.
Update for Swift 3:
let letters = CharacterSet.letters
let digits = CharacterSet.decimalDigits
var letterCount = 0
var digitCount = 0
for uni in phrase.unicodeScalars {
if letters.contains(uni) {
letterCount += 1
} else if digits.contains(uni) {
digitCount += 1
}
}
(Previous answer for older Swift versions)
A possible Swift solution:
var letterCounter = 0
var digitCount = 0
let phrase = "The final score was 32-31!"
for tempChar in phrase.unicodeScalars {
if tempChar.isAlpha() {
letterCounter++
} else if tempChar.isDigit() {
digitCount++
}
}
Update: The above solution works only with characters in the ASCII character set,
i.e. it does not recognize Ä, é or ø as letters. The following alternative
solution uses NSCharacterSet from the Foundation framework, which can test characters
based on their Unicode character classes:
let letters = NSCharacterSet.letterCharacterSet()
let digits = NSCharacterSet.decimalDigitCharacterSet()
var letterCount = 0
var digitCount = 0
for uni in phrase.unicodeScalars {
if letters.longCharacterIsMember(uni.value) {
letterCount++
} else if digits.longCharacterIsMember(uni.value) {
digitCount++
}
}
Update 2: As of Xcode 6 beta 4, the first solution does not work anymore, because
the isAlpha() and related (ASCII-only) methods have been removed from Swift.
The second solution still works.
Use the values of unicodeScalars
let phrase = "The final score was 32-31!"
var letterCounter = 0, digitCounter = 0
for scalar in phrase.unicodeScalars {
let value = scalar.value
if (value >= 65 && value <= 90) || (value >= 97 && value <= 122) {++letterCounter}
if (value >= 48 && value <= 57) {++digitCounter}
}
println(letterCounter)
println(digitCounter)
For Swift 5 you can do the following for simple strings, but be vigilant about handling characters like "1️⃣" , "④" these would be treated as numbers as well.
let phrase = "The final score was 32-31!"
var numberOfDigits = 0;
var numberOfLetters = 0;
var numberOfSymbols = 0;
phrase.forEach {
if ($0.isNumber) {
numberOfDigits += 1;
}
else if ($0.isLetter) {
numberOfLetters += 1
}
else if ($0.isSymbol || $0.isPunctuation || $0.isCurrencySymbol || $0.isMathSymbol) {
numberOfSymbols += 1;
}
}
print(#"\#(numberOfDigits) || \#(numberOfLetters) || \#(numberOfSymbols)"#);
I've created a short extension for letter and digits count for a String
extension String {
var letterCount : Int {
return self.unicodeScalars.filter({ CharacterSet.letters.contains($0) }).count
}
var digitCount : Int {
return self.unicodeScalars.filter({ CharacterSet.decimalDigits.contains($0) }).count
}
}
or a function to get a count for any CharacterSet you put in
extension String {
func characterCount(for set: CharacterSet) -> Int {
return self.unicodeScalars.filter({ set.contains($0) }).count
}
}
usage:
let phrase = "the final score is 23-13!"
let letterCount = phrase.characterCount(for: .letters)
In case you only need one information (letter or number or sign) you can do it in one line:
let phrase = "The final score was 32-31!"
let count = phrase.filter{ $0.isLetter }.count
print(count) // "16\n"
But doing phrase.filter several times is inefficient because it loops through the whole string.

I don't know how to make them add or subtract, its there a way to do so. Basically I want 1"+"3 = 4 but I get 1+3 [duplicate]

This question already has answers here:
Swift - Resolving a math operation in a string
(4 answers)
Closed 6 years ago.
let randsign = Int(arc4random_uniform(2) + 1)
//This function returns a random operator
func whatSign(par1:Int)-> String {
if (par1 == 1){
return "+"
}
else {
return "-"
}
}
var sigh = whatSign(par1: randsign)
let randnum1:Any = Int (arc4random_uniform(10) + 1)
let randnum2:Int = Int (arc4random_uniform(10) + 1)
//I want the variable "finVal" to perform mathematical operation, but it does not because the variable "sign" is String
let finVal = "\(randnum1)\(sigh)\(randnum2)"
print(finVal)
//When I print I get for example 1-3, 9-4, 8+2 .But I wanted them to do arithmetic
NSExpression is one the good way to evaluate the Math
let finVal = "(randnum1)(sigh)(randnum2)"
let result = NSExpression(format: finVal).expressionValue(with: nil, context: nil) as! Int
let randsign = Int(arc4random_uniform(2) + 1)
let randnum1:Any = Int (arc4random_uniform(10) + 1)
let randnum2:Int = Int (arc4random_uniform(10) + 1)
var finVal:Int
//This function returns a random operator
func whatSign(par1:Int)-> String {
//I want to compute the variables and get final result from adding or subtracting them
if (par1 == 1){
finVal = randnum1 + randnum2
return "+"
}
else {
finVal = randnum1 - randnum2
return "-"
}
}
whatSign(par1: randsign)
print(finVal)
//When I print I get for example 1-3, 9-4, 8+2 .But I wanted them to do arithmetic
Maybe it will helps you

The code works, but not sure how to implement it into iOS [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I'm currently taking a chemistry class and thought it would be fun to make a program that can calculate the pH of strong/weak acid solutions. The code works in playgrounds and I'd like to eventually implement it into an iOS project. The program takes in 3 parameters: the initial concentration of the acid, the acid's chemical formula, and the equilibrium constant of the acid (if needed). The program begins by taking in the initial concentration of the acid, then it takes in the chemical formula of the acid and determines if the acid is strong or weak. Next, I set up an if statement to calculate the pH according to the strength of the acid. If the acid is weak, an equilibrium constant is needed. Here is what I have so far:
import UIKit
func acidConcentration(acidMolarity: Double) -> Double {
return acidMolarity
}
let initialConcentration = acidConcentration(0.50)
var hydroniumConcentration = 0.00
var pH = 0.00
func determineAcidStrength(acidName: String) -> String {
var acidStrength = ""
if acidName=="HBr" || acidName=="HI" || acidName=="HClO4" || acidName=="HCl" || acidName=="HClO3" || acidName=="H2SO4" || acidName=="HNO3" {
acidStrength = "strong"
} else {
acidStrength = "weak"
}
return acidStrength
}
let strength = determineAcidStrength("HBr")
if strength == "strong" {
hydroniumConcentration = initialConcentration
pH = -log10(hydroniumConcentration)
print(String(format: "%.2f", pH))
} else {
func equilibriumConstant(ka: Double) -> Double {
return ka
}
let eqConstant = equilibriumConstant
var weakAcidConcentration = sqrt(eqConstant(1.8e-5) * initialConcentration)
pH = -log10(weakAcidConcentration)
print(String(format: "%.2f", pH))
}
As I am very new to programming and this is my first attempt at writing any code, I was wondering if there are any ways to clean up what I have or any tips to organize the code better. Any help is appreciated. Thanks.
The code that you have posted is overly complicated for something that can be accomplished in a single function.
The function below accepts 2 arguments, the acidName as a String, and the initialConcentration as a Double and returns the concentration as a Double value.
func calculateConcentration(acidName: String, initialConcentration: Double) -> Double {
var acidIsStrong = false;
if acidName=="HBr" || acidName=="HI" || acidName=="HClO4" || acidName=="HCl" || acidName=="HClO3" || acidName=="H2SO4" || acidName=="HNO3" {
acidIsStrong = true;
}
if acidIsStrong {
return -log10(initialConcentration);
} else {
return -log10( (1.8e-5) * initialConcentration);
}
}
Here is an example use of the function:
//Just pass in your acid name and initial concentration
let concentration = calculateConcentration("HBr", initialConcentration: 0.50);
print(String(format: "%.2f", concentration));
Here is a smaller version of the function written a bit more efficiently (it works the same):
func calculateConcentration(acidName: String, initialConcentration: Double) -> Double {
if acidName=="HBr" || acidName=="HI" || acidName=="HClO4" || acidName=="HCl" || acidName=="HClO3" || acidName=="H2SO4" || acidName=="HNO3" {
return -log10(initialConcentration);
}
return -log10( (1.8e-5) * initialConcentration);
}
And an even smaller version that isn't very readable:
func calculateConcentration(acidName: String, initialConcentration: Double) -> Double {
return -log10( initialConcentration * ((acidName=="HBr" || acidName=="HI" || acidName=="HClO4" || acidName=="HCl" || acidName=="HClO3" || acidName=="H2SO4" || acidName=="HNO3") ? (1.8e-5) : 1.0));
}
I'm not much of a chemist so, I'm not sure about the formula, but how about this:
class Acid: CustomStringConvertible {
static let strongAcids = [ "HBr", "HI", "HClO4", "HCl", "HClO3", "H2SO4", "HNO3" ]
var name: String
var concentration: Double
var equilibriumConstant: Double?
var pH: Double {
get {
var adjustedConcentration = concentration
if !Acid.strongAcids.contains(name) {
guard let ka = equilibriumConstant else {
return Double.NaN;
}
adjustedConcentration = sqrt(ka * concentration)
}
return -log10(adjustedConcentration)
}
}
init(name: String, concentration: Double, equilibriumConstant ka: Double? = nil) {
self.name = name
self.concentration = concentration
self.equilibriumConstant = ka
}
var description: String {
get {
if let ka = equilibriumConstant {
return "\(name) (concentration: \(concentration) / EqK: \(ka) pH: \(String(format: "%.2f", pH)))"
} else {
return "\(name) (concentration: \(concentration) / pH: \(String(format: "%.2f", pH)))"
}
}
}
}
let acid = Acid(name: "HBr", concentration: 0.5);
print("\(acid)") // prints "HBr (concentration: 0.5 / pH: 0.30)"
print(String(format: "%.2f", acid.pH)) // prints "0.30"
let weakAcid = Acid(name: "Weak", concentration: 0.2, equilibriumConstant: 1.8e-5)
print("\(weakAcid)") // prints "Weak (concentration: 0.2 / EqK: 1.8e-05 pH: 2.72)"
As for creating an app... For a simple app like this, you can probably just create a "Single View Application" with 3 text fields (name, concentration, and constant) and a button the "calculate". I hope that makes sense.

How to find out if letter is Alphanumeric or Digit in Swift

I want to count the number of letters, digits and special characters in the following string:
let phrase = "The final score was 32-31!"
I tried:
for tempChar in phrase {
if (tempChar >= "a" && tempChar <= "z") {
letterCounter++
}
// etc.
but I'm getting errors. I tried all sorts of other variations on this - still getting error - such as:
could not find an overload for '<=' that accepts the supplied arguments
For Swift 5 see rustylepord's answer.
Update for Swift 3:
let letters = CharacterSet.letters
let digits = CharacterSet.decimalDigits
var letterCount = 0
var digitCount = 0
for uni in phrase.unicodeScalars {
if letters.contains(uni) {
letterCount += 1
} else if digits.contains(uni) {
digitCount += 1
}
}
(Previous answer for older Swift versions)
A possible Swift solution:
var letterCounter = 0
var digitCount = 0
let phrase = "The final score was 32-31!"
for tempChar in phrase.unicodeScalars {
if tempChar.isAlpha() {
letterCounter++
} else if tempChar.isDigit() {
digitCount++
}
}
Update: The above solution works only with characters in the ASCII character set,
i.e. it does not recognize Ä, é or ø as letters. The following alternative
solution uses NSCharacterSet from the Foundation framework, which can test characters
based on their Unicode character classes:
let letters = NSCharacterSet.letterCharacterSet()
let digits = NSCharacterSet.decimalDigitCharacterSet()
var letterCount = 0
var digitCount = 0
for uni in phrase.unicodeScalars {
if letters.longCharacterIsMember(uni.value) {
letterCount++
} else if digits.longCharacterIsMember(uni.value) {
digitCount++
}
}
Update 2: As of Xcode 6 beta 4, the first solution does not work anymore, because
the isAlpha() and related (ASCII-only) methods have been removed from Swift.
The second solution still works.
Use the values of unicodeScalars
let phrase = "The final score was 32-31!"
var letterCounter = 0, digitCounter = 0
for scalar in phrase.unicodeScalars {
let value = scalar.value
if (value >= 65 && value <= 90) || (value >= 97 && value <= 122) {++letterCounter}
if (value >= 48 && value <= 57) {++digitCounter}
}
println(letterCounter)
println(digitCounter)
For Swift 5 you can do the following for simple strings, but be vigilant about handling characters like "1️⃣" , "④" these would be treated as numbers as well.
let phrase = "The final score was 32-31!"
var numberOfDigits = 0;
var numberOfLetters = 0;
var numberOfSymbols = 0;
phrase.forEach {
if ($0.isNumber) {
numberOfDigits += 1;
}
else if ($0.isLetter) {
numberOfLetters += 1
}
else if ($0.isSymbol || $0.isPunctuation || $0.isCurrencySymbol || $0.isMathSymbol) {
numberOfSymbols += 1;
}
}
print(#"\#(numberOfDigits) || \#(numberOfLetters) || \#(numberOfSymbols)"#);
I've created a short extension for letter and digits count for a String
extension String {
var letterCount : Int {
return self.unicodeScalars.filter({ CharacterSet.letters.contains($0) }).count
}
var digitCount : Int {
return self.unicodeScalars.filter({ CharacterSet.decimalDigits.contains($0) }).count
}
}
or a function to get a count for any CharacterSet you put in
extension String {
func characterCount(for set: CharacterSet) -> Int {
return self.unicodeScalars.filter({ set.contains($0) }).count
}
}
usage:
let phrase = "the final score is 23-13!"
let letterCount = phrase.characterCount(for: .letters)
In case you only need one information (letter or number or sign) you can do it in one line:
let phrase = "The final score was 32-31!"
let count = phrase.filter{ $0.isLetter }.count
print(count) // "16\n"
But doing phrase.filter several times is inefficient because it loops through the whole string.

Resources