Cave007 - 1 year ago 89
Swift Question

# Textfield as input in average function

I recently wanted to code an Average-Calculator.
My plan was to build a

`UITextField`
in which you can type Numbers separated by commas... By pressing the 'Calculate' button the App should calculate the Average of the Numbers above and give them out by setting a labeltext to the average.
So I wrote my average function and received this error message:

Can not convert value of type 'UITextField' to expected element type 'Double'.

This is my Code:

``````@IBOutlet var Input: UITextField!
@IBOutlet var Output: UILabel!
@IBAction func Calculate(sender: AnyObject) {

func average(nums: [Double]) -> Double {

var total = 0.0

}

return average
}

Output.text = "Average: \(Average)"
}
``````

Can you help me with my idea?
Is there a better way to get an input?

Please use lower camel case for variables...

In this line:

``````var grades:[Double] = [Input]
``````

`Input` is an instance of `UITextField`, so you are trying to assign a single-element `Array<UITextField>` to `Array<Double>`. You see you cannot do such sort of things.

If you want to accept a text which contains Numbers separated by commas, you need to explicitly convert the `text` to `[Double]`.

To simplify, let's just ignore the `nil` or non-numeric values. Then you need to change your code as:

``````@IBOutlet var input: UITextField!
@IBOutlet var output: UILabel!
@IBAction func calculate(sender: AnyObject) {

var grades: [Double] = (input.text ?? "").componentsSeparatedByString(",").flatMap{Double(\$0)}
func average(nums: [Double]) -> Double {

var total = 0.0

}

return average
}

output.text = "Average: \(averageValue)"
}
``````

The basic idea of this line:

``````var grades: [Double] = (input.text ?? "").componentsSeparatedByString(",").flatMap{Double(\$0)}
``````

is well-described in Lu_'s answer. Mine is just a little safer version.

`UITextField`s property `text` is of type `String?`, so you should think it can be nil. Giving a default value for nil with `??` operator.

And using `Double(\$0)!` may crash your app, as `Double(\$0)` will return nil for non-numeric strings.

Writing these reminded me one more crash case.

When `gradesTotal` == 0, the code above will crash with division by zero.

(The `default` value does not work well for "safety" in the code above...)

So, one more step ahead to safety:

``````@IBAction func calculate(sender: AnyObject) {

var grades: [Double] = (input.text ?? "").componentsSeparatedByString(",").flatMap{
Double(\$0.stringByTrimmingCharactersInSet(.whitespaceCharacterSet()))
}
func average(nums: [Double]) -> Double? {

var total = 0.0

}

return average
} else {
return nil
}
}

if let averageValue = average(grades) {
output.text = "Average: \(averageValue)"
} else {
output.text = "Average not available"
}
}
``````
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download