Returning Value in if else error - swift

I have a dateFormatted and I am getting the date from API. I have got the value let's say 28 from 28th April 2018. So, I have to add the beside this 28 in Swift? Do anyone know this?
Else what I am trying is to set the values as "th" or "st" according to dates. I know the logics. I am just stuck with this:
let dateText = dateFormatterPrint.string(from: date)
if(dateText >= 4 && dateText <= 20) {
print("I am th")
}
Here it says, Binary operator '>=' cannot be applied to operands of type Int and String. I want to check for the value in this range?
Can anyone please help?
P.S. I got this and when printing I am getting values correctly, but when I return I get an error
if((count! >= 4 && count! <= 20) || (count! >= 24 && count! <= 30)){
return textVal = "I am th"
} else if(count! == 1 || count! == 21 || count! == 31) {
return textVal = "I am st"
} else if(count! == 2 || count! == 22) {
return textVal = "I am nd"
} else if(count! == 3 || count! == 23) {
return textVal = "I am rd"
} else {
print("I am known")
}
Use of unresolved identifier 'textVal'
Can anyone help?

The error occurs because you cannot return a variable which has never been declared
I recommend to use a switch statement
var dateText = dateFormatterPrint.string(from: date)
switch (dateText) {
case "1", "21", "31": dateText.append("st")
case "2", "22": dateText.append("nd")
case "3","23": dateText.append("rd")
default: dateText.append("th")
}
print(dateText)

It looks like you're trying to format an "ordinal number". The best way to do that is to configure a NumberFormatter to use a ordinal number style:
let ordinalNumberFormatter = NumberFormatter()
ordinalNumberFormatter.numberStyle = .ordinal
// for example...
ordinalNumberFormatter.string(from: 22) // "22nd"
ordinalNumberFormatter.string(from: 28) // "28th"
ordinalNumberFormatter.string(from: 31) // "31st"

We can't compare a String and an Int
if(dateText >= "4" && dateText <= "20")
{
print("I am th")
}

Related

swift reading integer quesiton

I'm new to swift programming. I compile my programs in windows or online compiler. I stucked reading an integer in swift. I succesfully read integer from console. But I can't use this integer variable in a while loop. How can I use integer variable in while loop that read from console?
my attempt is:
import Foundation
print("Enter a number:")
let inputNumber = Int(readLine()!)
if let inputNumber = inputNumber {
print(inputNumber)
}
if inputNumber == 3 {
print("number = 3") }
else { print("number != 3") }
var sayi = inputNumber
if sayi == 3 {
print("sayi = 3") }
else { print("sayi != 3") }
while sayi > 0 {
print("*", terminator:"")
sayi = sayi - 1 }
compile errors are:
main.swift:21:12: error: binary operator '>' cannot be applied to operands of type 'Int?' and 'Int'
while sayi > 0 {
~~~~ ^ ~
main.swift:21:12: note: overloads for '>' exist with these partially matching parameter lists: (Self, Self), (Self, Other)
while sayi > 0 {
^
main.swift:23:16: error: value of optional type 'Int?' not unwrapped; did you mean to use '!' or '?'?
sayi = sayi - 1
The problem is that inputNumber and sayi are optional values and the compiler consider Int and Int? to be different types that it can't compare
I would use the following logic to read and convert the user input
let inputNumber: Int
//The below if clause will be successful only if both deadline() and Int() returns non-nil values
if let input = readLine(), let value = Int(input) {
inputNumber = value
} else {
print("Bad input")
inputNumber = 0
}
and then the rest of the code will work (here I simplified it somewhat)
var sayi = inputNumber
sayi == 3 ? print("sayi = 3") : print("sayi != 3")
while sayi > 0 {
print("*", terminator:"")
sayi -= 1
}

Converting Optional String to Int in Swift 4

I'm trying to make a call from my JSON file where the variable is a string however in order to compare it I would want it to be an integer, however, whenever I try and convert it using methods on here nothing seems to be working, assuming the wrong syntax. This line essentially (pData.info?.nutriScore ?? 0) prints a score however its a string.
if let nScore = Int(pData.info?.myScore ?? 0) < 0 {
//Other Code
}
if let nutriScore = pData.info?.nutriScore, let nScore = Int(nutriScore) {
// your code here
}
You need
if let nScore = Int(pData.info?.myScore ?? "0" ) , nScore > 0 {
}
if let nScore:Int = Int(pData.info?.nutriScore ?? "0") {
if nScore < 0 {
print(nScore)
}
}
Avoid using ?? default value ,
Yes you dont have the value in your object so you are passing the default that doesnt mean default value is your Real data .
if let b = pData.info?.myScore, let nScore = Int(b) , nScore >= 0{
print(nScore)
} else {// handle negative logic}

Swift on array.sort - Expression was too complex to be solved in reasonable time; consider breaking up the expression into distinct sub-expressions

I am downgrading Swift code from Xcode 8.3.1 to Xcode 7.3.1.
The Swift compiler of Xcode 7.3.1 raises
Expression was too complex to be solved in reasonable time; consider breaking up the expression into distinct sub-expressions
while pointing on line zeroParameterAndPaths.sort {. The code was ok in Xcode 8.3.1.
What's wrong and how to fix it?
class NewConnectingSegmentZeroParameterAndPath {
let step : Int; // 0 = main, 1 = first outline, 2 = second outline
let parameter : CGFloat;
init(step: Int, parameter: CGFloat) {
self.step = step;
self.parameter = parameter;
}
}
var zeroParameterAndPaths : [NewConnectingSegmentZeroParameterAndPath] = [];
// ... some zeroParameterAndPaths .appendContentsOf calls
zeroParameterAndPaths.sort {
return $0.parameter < $1.parameter
|| ($0.parameter == $1.parameter
&& ($0.step == 1 || ($0.step == 0 && $1.step == 2))
)
};
You have two choices. One is simply to do what the error message suggests, i.e. pulling the complex bool apart into separate pieces:
zeroParameterAndPaths.sort {
let bless = ($0.parameter < $1.parameter)
let beq = ($0.parameter == $1.parameter)
let band = ($0.step == 0 && $1.step == 2)
let bor = ($0.step == 1 || band)
let beqandbor = (beq && bor)
return (bless || beqandbor)
};
The other is to provide an explicit in line giving the param types and result type:
zeroParameterAndPaths.sort {
(a:NewConnectingSegmentZeroParameterAndPath, b:NewConnectingSegmentZeroParameterAndPath) -> Bool in
return a.parameter < b.parameter
|| (a.parameter == b.parameter
&& (a.step == 1 || (a.step == 0 && b.step == 2))
)
};
You could also make your class a little bit more helpful and make it implement the condition. The compiler is much less likely to get confused in a function body than in a closure:
class NewConnectingSegmentZeroParameterAndPath {
let step : Int; // 0 = main, 1 = first outline, 2 = second outline
let parameter : CGFloat;
init(step: Int, parameter: CGFloat) {
self.step = step;
self.parameter = parameter;
}
func orderedBefore(_ other: NewConnectingSegmentZeroParameterAndPath) -> Bool
{
return parameter < other.parameter
|| parameter == other.parameter
&& (step == 1 || step == 0 && other.step == 2)
}
}
var zeroParameterAndPaths : [NewConnectingSegmentZeroParameterAndPath] = [];
// ... some zeroParameterAndPaths .appendContentsOf calls
zeroParameterAndPaths.sort { $0.orderedBefore($1) }
Apart from the issue of the type inference engine not being able to quickly resolve such complex bool expressions, such expressions are really hard to follow. I suggest you break it down into something simpler, like so:
zeroParameterAndPaths.sort {
if $0.parameter != $1.parameter { return $0.parameter < $1.parameter ]
if $0.step == 1 { return true }
if $0.step == 0 && $1.step == 2 { return true }
return false
};
There's my attempt at it. I'm not even sure if it's correct, the original expression is pretty hard to follow.

Value of type 'String' has no member 'range' in Swift

I believe I've run into a Swift versioning issue but I'm not too sure. The code works in my Xcode platform but not in an online swift compiler. Has anyone else run into this issue or know what I can use to replace the following lines where I check for a character:
if i == 0 || !((line.range(of: ":") != nil))
Here is my code:
import Foundation
func hackTheString(line: String){
var maxOpen: Int = 0
var minOpen: Int = 0
minOpen = 0
maxOpen = 0
let i = 0
while i < line.characters.count {
for character in line.characters {
if character == "(" {
maxOpen += 1
if i == 0 || !((line.range(of: ":") != nil)) {
minOpen += 1
}
}
else if character == ")"{
minOpen = max(0,minOpen-1)
if i == 0 || !((line.range(of: ":") != nil)){
maxOpen -= 1;
}
if maxOpen < 0{
break
}
}
}
if maxOpen >= 0 && minOpen == 0{
print("YES")
}else{
print("NO")
}
}
}
while let line = readLine() {
print(hackTheString(line))
}
The error given from the online compiler is:
source.swift:17:37: error: value of type 'String' has no member 'range'
if i == 0 || !((line.range(of: ":") != nil)) {
^~~~ ~~~~~
source.swift:24:37: error: value of type 'String' has no member 'range'
if i == 0 || !((line.range(of: ":") != nil)){
^~~~ ~~~~~
I tried using range(of:) function on IBM's online swift compiler and I made sure to write import Foundation and it totally worked. Then I tried to see what version of swift is that online compiler using with following code:
#if swift(>=3.0)
print("Hello, Swift 3!")
#elseif swift(>=2.2)
print("Hello, Swift 2.2!")
#elseif swift(>=2.1)
print("Hello, Swift 2.1!")
#endif
That way I got to know that the online compiler I tried was using Swift 3 and hence the function worked perfect. Try checking what version your online compiler is using and use the related function specific to that version.
Other thing that you can do for now is use the characters array of your string and find the Index of your character. So your code might look like this:
if i == 0 || !((line.characters.index(of: ":") != nil)) {
minOpen += 1
}

Swift: How to use more than one 'where' on conditional binding?

I did some google searched and the examples use " , " to use more than one where statement but it doesn't work for me. I have tried && as well.
if let movesDict = pokemonInfoDict["moves"] as? [Dictionary<String,AnyObject>] where movesDict.count > 0, movesDict["learn_type"] == "level up"{
}
if let movesDict = pokemonInfoDict["moves"] as? [Dictionary<String,AnyObject>] where movesDict.count > 0 && movesDict["learn_type"] == "level up"{
}
Any help would be greatly appreciated thanks.
You want && - you must have some other problem with your code, as this works:
let foo: Int? = 10
if let bar = foo where bar > 8 && bar % 2 == 0 {
print("It works")
}
You tried this:
if let movesDict = pokemonInfoDict["moves"] as? [Dictionary<String,AnyObject>]
where movesDict.count > 0
&& movesDict["learn_type"] == "level up"
{
// ...
}
The problem is that movesDict is a array of dictionaries, and you tried to use the string "learn_type" as the subscript of that array when you said movesDict["learn_type"], but an array subscript must be an Int.