I'm trying to reads records from a .txt file and store them as a collection of structs but I am struggling to fix this error:
"Missing argument for parameter 'year' in call
This is my code:
struct DataSet: CustomStringConvertible {
var year: Int
var month: Int
var tmax: Double
var tmin: Double
var airfrost: Int
var rain: Double
var sun: Double
var description: String {
return "\(year) + \(month) + \(tmax) + \(tmin) + \(airfrost) + \(rain) + \(sun)"
}
}
let path = "/Users/sc16hsm/Desktop/CW2/data/bradford.txt"
var data = [DataSet]()
var temp = DataSet()
if let contents = try? String(contentsOfFile: path) {
let filtered = contents.components(separatedBy: "\n")
for line in filtered {
let x = line.components(separatedBy: " ").filter{$0 != ""}
let x = line.components(separatedBy: " ")
temp.year = Int(x[0])
temp.month = Int(x[1])
temp.tmax = Double(x[2])
temp.tmin = Double(x[3])
temp.airfront = Int(x[4])
temp.rain = Double(x[5])
temp.sun = Double(x[6])
data.append(temp)
print(x)
}
Any help would be greatly appreciated.
If the members of the struct don't have initial values you have to use the memberwise initializer. The default initializer doesn't work.
You have to write inside the loop
let temp = DataSet(year: Int(x[0])!,
month: Int(x[1])!,
tmax: Double(x[2])!,
tmin: Double(x[3])!,
airfrost: Int(x[4])!,
rain: Double(x[5])!,
sun: Double(x[6])!)
data.append(temp)
Please use code completion to get the complete syntax.
I'm trying to get the substring of the var num, but I need that substring be an Int How can I do that?
This is my code
func sbs_inicio(num: String, index: Int) -> Int{
let dato: Int = num.index(num.startIndex, offsetBy: index)
return dato
}
var num = "20932121133222"
var value = sbs_inicio(num: num, index: 2)
print(value) //value should be 20
Use the prefix function on the characters array
let startString = "20932121133222"
let prefix = String(startString.characters.prefix(2))
let num = Int(prefix)
Prefix allows you to get the first n elements from the start of an array, so you get these, convert them back to a String and then convert the resulting String to an Int
I am attempting to convert Int? to a String and assign it to a label without including the optional text. I currently have:
struct Choice: Mappable{
var id: String?
var choice: String?
var questionId: String?
var correct: Bool?
var responses: Int?
init?(map: Map) {
}
mutating func mapping(map: Map) {
id <- map["id"]
questionId <- map["questionId"]
choice <- map["choice"]
correct <- map["correct"]
responses <- map["responses"]
}
}
In the class accessing it
var a:String? = String(describing: self.currentResult.choices?[0].responses)
print("\(a!)")
and the output is:
Optional(1)
How would I make it just output 1 and remove the optional text?
a is an Optional, so you need to unwrap it prior to applying a String by Int initializer to it. Also, b needn't really be an Optional in case you e.g. want to supply a default value for it for cases where a is nil.
let a: Int? = 1
let b = a.map(String.init) ?? "" // "" defaultvalue in case 'a' is nil
Or, in case the purpose is to assign the possibly existing and possibly String-convertable value of a onto the text property of an UILabel, you could assign a successful conversion to the label using optional binding:
let a: Int? = 1
if let newLabelText = a.map(String.init) {
self.label.text = newLabelText
}
Why don't?
let a : Int = 1
var b = "\(a)"
print(b)
so
$ swift
[ 9> let a : Int = 1
a: Int = 1
[ 10> var b = "\(a)"
b: String = "1"
[ 11> print(b)
1
By the way there are other options like this one
12> var c = a.description
c: String = "1"
13> print(c)
1
I want to be able to compare values from the [String] level instead of the String level. Here's what I mean:
var connectedNames:[[[String]]] = [[[]]]
for var row: Int = 0; row < connectedNames[0].count; row++ {
if self.connectedNames[0][row] as! String == "asdf" {
}
}
But the cast here from [String] to String fails so I can't make this value comparison.
So the main problem is this: Is there anyway to compare the String value of a [[String]] to a String? In other words, the String value that I get from indexing connectedNames like so connectedNames[0][0] == "Some String"?
You can only compare [[String]] to String by using the subscript method of the Array to access the inner element. This would work:
func compare() -> Bool {
let arr: [[String]] = [["foo"]]
let str: String = "foo"
guard let innerArr = arr[0] else {
return false
}
guard let element = innerArr[0] else {
return false
}
return element == str
}
In Swift, i cant cast Int to String by:
var iString:Int = 100
var strString = String(iString)
But my variable in Int? , there for error: Cant invoke 'init' with type '#Ivalue Int?'
Example
let myString : String = "42"
let x : Int? = myString.toInt()
if (x != null) {
// Successfully converted String to Int
//And how do can i convert x to string???
}
You can use string interpolation.
let x = 100
let str = "\(x)"
if x is an optional you can use optional binding
var str = ""
if let v = x {
str = "\(v)"
}
println(str)
if you are sure that x will never be nil, you can do a forced unwrapping on an optional value.
var str = "\(x!)"
In a single statement you can try this
let str = x != nil ? "\(x!)" : ""
Based on #RealMae's comment, you can further shorten this code using the nil coalescing operator (??)
let str = x ?? ""
I like to create small extensions for this:
extension Int {
var stringValue:String {
return "\(self)"
}
}
This makes it possible to call optional ints, without having to unwrap and think about nil values:
var string = optionalInt?.stringValue
If you need a one-liner it can be achieved by:
let x: Int? = 10
x.flatMap { String($0) } // produces "10"
let y: Int? = nil
y.flatMap { String($0) } // produces nil
if you need a default value, you can simply go with
(y.flatMap { String($0) }) ?? ""
EDIT:
Even better without curly brackets:
y.flatMap(String.init)
Apple's flatMap(_:) Documentation
Optional Int -> Optional String:
If x: Int? (or Double? - doesn't matter)
var s = x.map({String($0)})
This will return String?
To get a String you can use :
var t = s ?? ""
Hope this helps
var a = 50
var str = String(describing: a)
Crude perhaps, but you could just do:
let int100 = 100
println(int100.description) //Prints 100
Sonrobby, I believe that "Int?" means an optional int. Basically, by my understanding, needs to be unwrapped.
So doing the following works fine:
let y: Int? = 42
let c = String(y!)
That "!" unwraps the variable. Hope this helps!
As rakeshbs mentioned, make sure the variable won't be nill.
You need to "unwrap" your optional in order to get to the real value inside of it as described here. You unwrap an option with "!". So, in your example, the code would be:
let myString : String = "42"
let x : Int? = myString.toInt()
if (x != null) {
// Successfully converted String to Int
// Convert x (an optional) to string by unwrapping
let myNewString = String(x!)
}
Or within that conditional, you could use string interpolation:
let myNewString = "\(x!)" // does the same thing as String(x!)
For preventing unsafe optional unwraps I use it like below as suggested by #AntiStrike12,
if let theString = someVariableThatIsAnInt {
theStringValue = String(theString!))
}
Swift 3:
var iString:Int = 100
var strString = String(iString)
extension String {
init(_ value:Int){/*Brings back String() casting which was removed in swift 3*/
self.init(describing:value)
}
}
This avoids littering your code with the verbose: String(describing:iString)
Bonus: Add similar init methods for commonly used types such as: Bool, CGFloat etc.
You can try this to convert Int? to string
let myString : String = "42"
let x : Int? = myString.toInt()
let newString = "\(x ?? 0)"
print(newString) // if x is nil then optional value will be "0"
If you want an empty string if it not set (nil)
extension Int? {
var stringValue:String {
return self == nil ? "" : "\(self!)"
}
}