将 16 个 if 语句压缩成更简单的代码 Swift 游乐场

Condense 16 if statements into simpler code Swift Playground

我在 Swift 游乐场工作,我正在使用多个切换来确定某个动作是对还是错。从那里,它们的特定组合将显示分配给每个组合的数字。因为我有 4 个开关,所以我决定制作 16 个 if else 语句,但这确实减慢了我的操场。有没有办法使用less语句?

Toggle(isOn: $washingHandsToggle) {
                    Text("Washing Hands Regularly")
                }.padding(40)

                Toggle(isOn: $wearingMaskToggle) {
                    Text("Wearing a Protective Mask")
                }.padding(40)

                Toggle(isOn: $coverMouthToggle) {
                    Text("Cover your mouth and nose when coughing or sneezing")
                }.padding(40)

                Toggle(isOn: $quarantineToggle) {
                    Text("Quarantine")
                }.padding(40)


                if !washingHandsToggle && !wearingMaskToggle && !coverMouthToggle && !quarantineToggle {
                    self.r0 = 1.0
                }else if !washingHandsToggle && !wearingMaskToggle && coverMouthToggle && !quarantineToggle {
                    self.r0 = 2.0

                }else if washingHandsToggle && !wearingMaskToggle && !coverMouthToggle && !quarantineToggle {
                    self.r0 = 3.0

                }else if !washingHandsToggle && wearingMaskToggle && !coverMouthToggle && !quarantineToggle {
                    self.r0 = 4.0

                }else if washingHandsToggle && !wearingMaskToggle && coverMouthToggle && !quarantineToggle {
                    self.r0 = 5.0

                }else if !washingHandsToggle && wearingMaskToggle && coverMouthToggle && !quarantineToggle {
                    self.r0 = 6.0

                }else if washingHandsToggle && wearingMaskToggle && !coverMouthToggle && !quarantineToggle {
                    self.r0 = 7.0

                }else if washingHandsToggle && wearingMaskToggle && coverMouthToggle && !quarantineToggle {
                    self.r0 = 8.0

                }else if !washingHandsToggle && !wearingMaskToggle && !coverMouthToggle && quarantineToggle {
                    self.r0 = 9.0

                }else if !washingHandsToggle && !wearingMaskToggle && coverMouthToggle && quarantineToggle {
                    self.r0 = 10.0

                }else if washingHandsToggle && !wearingMaskToggle && !coverMouthToggle && quarantineToggle {
                    self.r0 = 11.0

                }else if !washingHandsToggle && wearingMaskToggle && !coverMouthToggle && quarantineToggle {
                    self.r0 = 12.0

                }else if washingHandsToggle && !wearingMaskToggle && coverMouthToggle && quarantineToggle {
                    self.r0 = 13.0

                }else if !washingHandsToggle && wearingMaskToggle && coverMouthToggle && quarantineToggle {
                    self.r0 = 14.0

                }else if washingHandsToggle && wearingMaskToggle && !coverMouthToggle && quarantineToggle {
                    self.r0 = 15.0

                }else {
                    self.r0 = 16.0
                }

我会将 4 个开关的状态转换为 1/0,然后将这些位映射为 4 位数字,给出 0-15 之间的值

let washingHands:Int = washingHandsToggle.isOn ? 1:0
let wearingMask:Int = wearingMaskToggle.isOn ? 1:0
let coverMouth:Int = coverMouthToggle.isOn ? 1:0
let quarantine:Int = quarantineToggle.isOn ? 1:0

let stateValue = washingHands <<3 
                 | wearingMask << 2 
                 | coverMouth << 1 
                 | quarantine

在我看来你可以将其转换为简单的数学运算,因为你只对值为真时的切换感兴趣

let value = (coverMouthToggle ? 1.0 : 0.0) +
    (washingHandsToggle ? 2.0 : 0.0) +
    (wearingMaskToggle ? 4.0 : 0.0) +
    (quarantineToggle ? 8.0 : 0.0)

(注意,您可能需要调整每个分数,因为我不确定我是否做对了)

我认为看到使用 Combine 的实现可能会很有趣。这不是 SwiftUI 代码,但由于 SwiftUI 自始至终都使用 Combine,因此适应起来应该不难。

在这个例子中,我们没有对四个开关的权重进行硬编码,而是将这些权重保存在一个数组中,weights,因此您可以根据需要分配或修改它们。开关是通过出口集合 toggles.

指向的 UISwitch 对象
import UIKit
import Combine
class ViewController: UIViewController {
    @IBOutlet var toggles: [UISwitch]!
    var publishers = [CurrentValueSubject<Bool, Never>]()
    var storage = [AnyCancellable]()
    let weights = [1.0, 0.7, 2.5, 1.3] // or whatever
    var sum = 0.0 {
        didSet { print(sum) }
    }
    @objc func routeToPublisher(_ toggle: UISwitch) {
        if let index = toggles.firstIndex(of: toggle) {
            publishers[index].send(toggle.isOn)
        }
    }
    override func viewDidLoad() {
        super.viewDidLoad()
        toggles.forEach {
            [=10=].addTarget(self, action: #selector(routeToPublisher), for: .valueChanged)
            publishers.append(CurrentValueSubject([=10=].isOn))
        }
        publishers[0].combineLatest(publishers[1], publishers[2], publishers[3]) { [[=10=],,,] }
            .map {
                [=10=].enumerated().map { pair in
                    (pair.element ? 1.0 : 0.0) * self.weights[pair.offset]
                }.reduce(0.0) {[=10=] + }
            }
            .assign(to: \.sum, on: self)
            .store(in: &storage)
    }
}

每次用户切换开关时,所有 "on" 个开关的加权和都会重新计算并显示在 self.sum 中,您可以用它做任何您想做的事情。在示例中我只是打印它,但显然你可以让它出现在界面中,发布和订阅它并在进一步的计算中使用它,等等。