【问题标题】:Condense 16 if statements into simpler code Swift Playground将 16 个 if 语句压缩成更简单的代码 Swift Playground
【发布时间】:2020-05-10 11:30:27
【问题描述】:

我在 Swift Playground 中工作,我正在使用多个切换来确定一个动作是真还是假。从那里,它们的特定组合将显示分配给每个组合的数字。因为我有 4 个切换,所以我决定做 16 个 if else 语句,但这确实减慢了我的操场速度。有没有办法使用更少的语句?

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
                }

【问题讨论】:

  • 首先,我会说它作为 Switch 语句看起来会更好。 r0 值有什么作用?您能否为每个切换分配一个值,例如 1、2、4、8 并将它们加起来,这将为您提供每个组合的唯一结果?
  • 看起来你希望他们没有采取任何预防措施时的最低值,以及他们良好时的最高值????????????。你有 4 个布尔值,有 16 种组合。查看 swift 的按位数据。基本上你想把每个布尔值当作一个位,所以 0000,直到 1111,然后你的数字就是那个二进制数的十进制转换。
  • @PeterParker 如果想使用特定数字(如 1.4、0.7、4.7)而不是 1-16,我应该怎么做

标签: ios swift swiftui swift-playground


【解决方案1】:

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

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

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

【讨论】:

  • 我有一些问题,因为 1.0:0 对我不起作用。有解决办法吗?
  • 我的问题是我不知道如何将切换的输出(真、假)转换为 1:0 和 2:0 的输出.....
  • @EliasFiz 我不确定我理解你的意思。
【解决方案2】:

我会将 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

【讨论】:

  • 非常感谢@Paulw11,但是如果想使用特定数字(如 1.4、0.7、4.7)而不是 0-15 我该怎么办
  • 用这些浮点值创建一个数组,并使用 0-16 作为该数组的索引
  • 我很抱歉,但我真的不明白我怎么能做到这一点。我了解数组部分,但如何收集 0-15 位数字?
  • 它将值组合起来,左移 3、2 或 1 个位置并将它们组合在一起,根据打开的开关为您提供 0 到 15 的值
【解决方案3】:

我认为看到使用 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 {
            $0.addTarget(self, action: #selector(routeToPublisher), for: .valueChanged)
            publishers.append(CurrentValueSubject($0.isOn))
        }
        publishers[0].combineLatest(publishers[1], publishers[2], publishers[3]) { [$0,$1,$2,$3] }
            .map {
                $0.enumerated().map { pair in
                    (pair.element ? 1.0 : 0.0) * self.weights[pair.offset]
                }.reduce(0.0) {$0 + $1}
            }
            .assign(to: \.sum, on: self)
            .store(in: &storage)
    }
}

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

【讨论】:

    猜你喜欢
    • 2022-01-28
    • 2016-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-11
    • 2019-05-06
    • 1970-01-01
    相关资源
    最近更新 更多