丢失一些if / else if statments!我应该用什么来取代它们? - SWIFT -

时间:2016-05-11 14:13:00

标签: arrays swift if-statement nested

我正在制作一个单位转换器,我使用的是这样的数组:

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和这个分支的菜鸟,但愿意学习......所以,任何帮助,例子和解释都会非常感激!!!!

3 个答案:

答案 0 :(得分:1)

首先,CentimeterMile存在于同一个数组中是没有意义的。无论如何,数组不是适合的数据结构选择。

我建议你为每种类型的单位(质量,体积,长度等)使用单独的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,但对于熟悉单位分析的人来说,我认为这很简单。