我正在制作一个单位转换器,我使用的是这样的数组:
private var subContentArray = [["Millimeter", "Centimeter", "Meter", "Kilometer", "Foot", "Yard", "Mile"],
["Milliliter", "Centiliter", "Liter", "Gallon", "Quart", "Pint", "Fluid ounce"],
["Milligram", "Centigram", "Gram", "Kilogram", "Stone", "Pound", "Ounce"]]
我正在使用一个设有3个piker字段的选择器:
func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
if pickerView.tag == 0 {
currentSelection = row
self.pickerGeneral.text = self.pickerGeneral1[row]
self.view.endEditing(true)
} else if pickerView.tag == 1 {
self.pickerTextField.text = self.pickerSubContent[currentSelection][row]
self.view.endEditing(true)
} else if pickerView.tag == 2 {
self.pickedTextField2.text = self.pickerSubContent[currentSelection][row]
self.view.endEditing(true)
}
}
我想通过常规选择器更改第2和第3选择器。到目前为止一切都很好,但后来我想进行计算,我试图做这样的事情:
func updateOutput(){
//var res: Double
var result: Double
if input.text!.isEmpty {
return
} else if pickerTextField.text! == "Centimeter" && pickedTextField2.text == "Mile" {
result = (Double(self.input.text!)! / 160934.4)
self.output.text! = String("\(result)")
} else if pickerTextField.text! == "Mile" && pickedTextField2.text! == "Centimeter" {
result = (Double(self.input.text!)! * 160934.4)
self.output.text! = String("\(result)")
} else if pickerTextField.text! == "Centimeter" && pickedTextField2.text == "Millimeter" {
result = (Double(self.input.text!)! * 10)
self.output.text! = String("\(result)")
} else if pickerTextField.text! == "Millimeter" && pickedTextField2.text! == "Centimeter" {
result = (Double(self.input.text!)! / 10)
self.output.text! = String("\(result)")
}
......直到我意识到,如果我要继续写作,如果......如果......我很快就会结束并且看起来会非常混乱!
我仍然是OOP和这个分支的菜鸟,但愿意学习......所以,任何帮助,例子和解释都会非常感激!!!!
答案 0 :(得分:1)
首先,Centimeter
和Mile
存在于同一个数组中是没有意义的。无论如何,数组不是适合的数据结构选择。
我建议你为每种类型的单位(质量,体积,长度等)使用单独的enumeration。枚举是一种存储有限的相关值的方法。在这种情况下,您可能会有LengthUnit
枚举:
enum LengthUnit {
case Millimeter
case Cenitmeter
case Meter
case Kilometer
//...
}
现在,您不是定义每个可能的单元对之间的显式关系,而是定义(在枚举中)每个单元和标准基本单元(例如仪表)之间的转换因子。然后,您将使用此标准基本单位作为从给定单位转换为所需单位的方式。
例如,如果我想将1.5公里转换为英里,我首先将1.5公里转换为米,使用从公里到米(1公里= 1000米)的转换,得到1500.然后我会使用倒数从英里到米的转换(1英里= 1609.34米)。总之,它将是:1.5km * (1000m/km) * (1 mile/1609.34m) = 0.93 miles
答案 1 :(得分:1)
您可以使用字典:
let factors : [(String, String): Double] = [("Centimeter", "Mile"): 1.0/160934.4,
("Mile", "Centimeter"): 160934.4,
<and more...>]
,您的功能变为
func updateOutput(){
if input.text!.isEmpty {
return
}
let result = (Double(self.input.text!)! * factors[(pickerTextField.text, pickerTextField2.text)]
self.output.text! = String("\(result)")
}
(警告:完全未经测试。)
使用通用基本单元会更好。
let in_meters: [String: Double] = ["Centimeter": 0.01,
"Meter": 1.0,
"Mile": 1609.344,
<and so on...>]
func updateOutput(){
if input.text!.isEmpty {
return
}
let meters = (Double(self.input.text!)! * in_meters[pickerTextField.text]
let result = meters * 1.0 / in_meters[pickerTextField2.text]
self.output.text! = String("\(result)")
}
答案 2 :(得分:0)
我明白为什么你的数组被分成几行:第0行是长度,第1行是体积,第2行是重量/质量。
您可以使用每对之间的转换创建相应的变量:
private var conversions = [[10, 100, 1000, 0.0003048, 3, 1760] .....
然后,一旦在一行中选择了开始和结束单位,则迭代conversions
并应用每一个单元直到达到所需的单位。 (如果朝一个方向前进,请务必增加,如果朝另一个方向前进,则分开。)
例如,从毫米到英尺,您将执行input / 10 / 100 / 1000 / 0.0003048
。如果从英尺到毫米,您将执行input * 0.0003048 * 1000 * 100 * 10
如果您的单位列表不经常更改,这将非常简单。您的if语句可以是从开始单元索引到结束单元索引的for循环迭代,并在每一步应用转换因子。
虽然这不是OO,但对于熟悉单位分析的人来说,我认为这很简单。