2016-07-22 3 views
0

Недавно я хотел закодировать Average-Calculator. Мой план состоял в том, чтобы построить UITextField, в котором вы можете вводить числа, разделенные запятыми ... Нажав кнопку «Рассчитать», приложение должно вычислить Среднее число номеров выше и выдавать их, установив ярлык в среднее значение. Так я написал функцию усреднения и получил сообщение об ошибке:Текстовое поле как входное значение в средней функции

Невозможно преобразовать значение типа «» UITextField к ожидаемому типу элемента «Double».

Это мой код:

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

    var grades:[Double] = [Input] 
    func average(nums: [Double]) -> Double { 

     var total = 0.0 
     for grade in nums{ 

      total += Double(grade) 
     } 

     let gradesTotal = Double(nums.count) 
     let average = total/gradesTotal 
     return average 
    } 

    let Average = average(grades) 

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

Можете ли вы помочь мне с моей идеей? Есть ли лучший способ получить вход?

+0

использовать 'Double (Input.text)'. Вы прямо сейчас назначаете объект текстового поля, чтобы удвоить –

ответ

2

Пожалуйста, используйте нижний корпус верблюда для переменных ...

В этой строке:

var grades:[Double] = [Input] 

Input является экземпляром UITextField, так что вы пытаетесь присвоить один-элемент Array<UITextField> в Array<Double>. Вы видите, что вы не можете делать такие вещи.

Если вы хотите, чтобы принять текст, который содержит чисел, разделенных запятыми, вам необходимо явно преобразовать text[Double] в.

Чтобы упростить, давайте просто проигнорируем nil или нечисловые значения. Тогда вам необходимо изменить свой код, как:

@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 
     for grade in nums{ 

      total += Double(grade) 
     } 

     let gradesTotal = Double(nums.count) 
     let average = total/gradesTotal 
     return average 
    } 

    let averageValue = average(grades) 

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

Основная идея этой линии:

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

хорошо описанный в ответ Lu_ в. Шахта - это немного более безопасная версия.


(Дополнение) Некоторые пояснения по поводу безопасности:

UITextField свойству объекта text имеет тип String?, так что вы должны думать, что может быть равен нулю. Дает значение по умолчанию для nil с оператором ??.

И с помощью Double($0)! может произойти сбой приложения, так как Double($0) вернет нуль для нечисловых строк.

Письмо это напомнило мне еще один случай аварии.

Когда gradesTotal == 0, код, указанный выше, сработает с делением на ноль.

(Значение default не работает хорошо для «безопасности» в приведенном выше коде ...)

Таким образом, еще один шаг вперед к безопасности:

@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 
     for grade in nums{ 

      total += Double(grade) 
     } 

     let gradesTotal = Double(nums.count) 
     if gradesTotal > 0 { 
     let average = total/gradesTotal 
      return average 
     } else { 
      return nil 
     } 
    } 

    if let averageValue = average(grades) { 
     output.text = "Average: \(averageValue)" 
    } else { 
     output.text = "Average not available" 
    } 
} 
+0

Большое вам спасибо! Это сработало! :) – Cave007

+0

Спасибо за сообщение. Помните, что этот ответ улучшен в сотрудничестве с сообществом Stack Overflow. И надеюсь, что ваш опыт поможет другим членам сообщества. Удачи вам и вашему приложению. – OOPer

+0

Я не знаю, почему, но когда я запускаю приложение, он разбивается на @IBOutlet var input: UITextField! Он работал отлично, но знаю, что он ломается каждый раз ... Я не думаю, что я что-то изменил ... Я даже удалил код, поэтому он должен только обладать View без каких-либо функций, но он тоже сломался ... – Cave007

0

Что вам нужно сделать, это использовать Double(Input.text) вместо [Input]. Прямо сейчас вы пытались преобразовать UITextField в двойное, что вызывает ошибку.

4

Вы должны отделить числа, чтобы получить этот массив, если вы сделаете это: enter image description here

вы можете передать «двойников» массив к вашей средней функции

код CopyPaste :)

var str = "1,2,3,4,5,6" 

let stringsWithNumbers = str.componentsSeparatedByString(",") 

let doubles = stringsWithNumbers.map { Double($0)! } 
+1

Nice! Это касается обеих проблем в вопросе. – sbarow

+1

случайно удалил комментарий, извините, просто хотел процитировать. Код добавил спасибо за напоминание об этом. –

+1

Добро пожаловать. Я стараюсь высвободить устаревшие комментарии как можно быстрее. – vacawama

0
let textInput = txtInputView.text; 
let components = textInput.componentsSeparatedByString(","); 
let sum = 0.0; 
for txt in components 
{ 
    sum = sum + Double(txt); 
} 

let avg = sum/components.count; 
print(avg) 
0

Вот полный код, если кто-то заинтересован :)

@IBOutlet var input: UITextField! 
@IBOutlet var output: UILabel! 
@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 
     for grade in nums{ 

      total += Double(grade) 
     } 

     let gradesTotal = Double(nums.count) 
     if gradesTotal > 0 { 
      let average = total/gradesTotal 
      return average 
     } else { 
      return nil 
     } 
    } 

    if let averageValue = average(grades) { 
     output.text = "Average: \(averageValue)" 
    } else { 
     output.text = "Average not available" 
    } 

} 

@IBAction func userTappedCalculate(sender: AnyObject) { view.endEditing(true) 
} 

Я добавил строку @IBAction func userTappedCalculate(sender: AnyObject) { view.endEditing(true) }, чтобы закрыть вход Tex tField, когда вы нажимаете подсчет ...

Смежные вопросы