Reputation: 9273
I'm parsing a 1970s-era text file (originally from the CDC 6600) which contains lines with variable numbers of parameters. Here are some samples...
GW 1 5 0.0000 -1.0000 0.0000000 0.00000 1.0000 0.000 .00667
GE 1
FR 0 0 0 0 46.29 0.
I am using split
(yay, finally fixed in Xcode 7!) to break this down into an array, and then insert non-zero values into a dictionary, like this...
let parts: [String] = original!.characters.split{ $0 == " " || $0 == "," }.map{ String($0).trim() }
if parts.count > 1 { data["I1"] = parts[1] }
if parts.count > 2 { data["I2"] = parts[2] }
if parts.count > 3 { data["F1"] = parts[3] }
Finally, I sanity check the inputs, because I've seen many examples of incorrect files. So I have a series of functions like this...
func checkGA() {
if (data["I1"] == "" || data["I2"] == "" || data["F1"] == "" || data["F2"] == "" || data["F3"] == "" || data["F4"] == "") { problem = "Missing parameters." }
if (data["F5"] != "" || data["F6"] != "" || data["F7"] != "") { problem = "Extra paramters after F4." }
}
I have a feeling there might be a less ugly way to check these inputs in Swift. I was thinking that perhaps I could use the range operator in a map or similar? Something along the lines of:
if (data["F2"..."F4"] != "") ...
But this sort of functional programming is very very new to me. Any gurus have a suggestion?
Upvotes: 2
Views: 320
Reputation: 844
You can create extension to dictionary:
extension Dictionary {
func keysExistsAndNotEmpty(keysArray: [Key]) -> Bool {
for key in keysArray {
if (self[key] as! String).isEmpty {
return false
}
}
return true
}
}
and after check your dictionary this way:
let data = ["a": "a", "b": "b"]
let keysArray = ["a", "b"]
if !data.keysExistsAndNotEmpty(keysArray) {
// throw error
}
Upvotes: 0
Reputation: 1285
You might consider using error handling:
enum FieldError : ErrorType {
case MissingField(String)
case ExtraField(String,String)
}
do {
// sample data
let data = ["I1": "hello", "I2": "world", "F1":"Greetings" ]
try ["I1", "I2", "F1"].forEach { key in
guard let value = data[key] where value != "" else {
throw FieldError.MissingField(key)
}
}
try ["F5", "F6", "F7", "F8"].forEach { key in
if let value = data[key] where value != "" {
throw FieldError.ExtraField(key, value)
}
}
print("All data tests passed")
}
catch FieldError.MissingField(let key) {
print("Missing field for key: \(key)")
}
catch let FieldError.ExtraField(key, value) {
print("Extra field with key: \(key), value: \(value)")
}
Upvotes: 1