Итак, как уже упоминали люди, использование Measurement
API упростит ситуацию, но я не думаю, что это реальная проблема с вашим кодом. Кажется, вы знаете, что с увеличением количества единиц, которые вы конвертируете в / из, ваша weightMath
функция быстро выходит из-под контроля (если у вас N единиц, она будет расти пропорционально N ^ 2). Хорошо, что, даже будучи новичком, вы смотрите на этот код и думаете: «Конечно, есть лучший способ».
Главное, что вам не хватает, - это вместо того, чтобы переходить непосредственно от входных единиц к выходным единиц вы должны разбить это на два шага. Выберите какой-нибудь внутренний блок (скажем, килограммы), затем переведите входные данные в эти внутренние блоки и переведите из этих внутренних блоков в выходные блоки.
Давайте посмотрим, как это будет выглядеть в коде. Несмотря на то, что ваша функция называется weightMath
, на самом деле она немного мешает работе с пользовательским интерфейсом. Давайте решим это, разбив его на две функции: updateUI
, который имеет дело с пользовательским интерфейсом, и convert
, который выполняет математику.
Здесь код для updateUI
:
func updateUI(_ input: UITextField, _ textField: UITextField) {
guard let inputString = input.text,
let inputValue = Double(inputString) else {
// You may want to do more than just return.
return
}
let convertedValue = convert(mass: inputValue, inputUnitIndex: input.tag, outputUnitIndex: textField.tag)
textField.text = String(format: "%.3f", convertedValue)
}
Теперь convert
может сосредоточиться только на математике. Даже без использования Measurement
API мы можем реализовать это довольно просто:
private func convert(mass: Double, inputUnitIndex: Int, outputUnitIndex: Int) -> Double {
let conversionTable = [ 1.0, 0.0283495, 0.453592 ]
let massKg = mass * conversionTable[inputUnitIndex]
return massKg / conversionTable[outputUnitIndex]
}
Несколько замечаний здесь. Таблица преобразования содержит факторы, необходимые для перевода килограммов, унций и фунтов в килограммы путем умножения. Этот же набор значений можно использовать для преобразования из килограммов путем деления. Значение massKg
- это значение в наших внутренних единицах , которое я выбрал в килограммах.
Но этот код немного уродлив: он имеет волхвов c констант , и если вы хотите поддерживать больше единиц, вам придется искать коэффициенты пересчета. Использование Measurement
API сделает это намного лучше. Вот как это выглядело бы.
private func convert(mass: Double, inputUnitIndex: Int, outputUnitIndex: Int) -> Double {
let unitLookupTable = [ UnitMass.kilograms, UnitMass.ounces, UnitMass.pounds ]
let massKg = Measurement(value: mass, unit: unitLookupTable[inputUnitIndex])
return massKg.converted(to: unitLookupTable[outputUnitIndex]).value
}
Есть еще кое-что, что можно сделать, чтобы сделать это намного приятнее: передача целых чисел здесь не велика ... но это другая история. Надеюсь, это поможет.