【问题标题】:How to update all items in Array in the correct way如何以正确的方式更新 Array 中的所有项目
【发布时间】:2018-06-30 03:14:38
【问题描述】:

有货币汇率数组,在 inputTextField 中输入金额后,我想更新此数组中的所有项目,以这种货币的金额并将其放在 tableView 中,尝试使用循环执行此操作,但这不正确因为这是每个循环都放在表中的解决方案

inputTextField 是文本字段的名称

receivedRates:[Double] = [1.1,1.6,2.0,1.3] // just example of the rates

for i in receivedRates {

    let newValue = Double(i)*Double(Int(inputTextField.text!)!)
    currentAmount.append(newValue)
    receivedRates = currentAmount
}

如何在没有循环的情况下更新这个数组,或者这个循环是否有其他解决方案?

【问题讨论】:

    标签: ios arrays swift insert-update items


    【解决方案1】:

    您还可以扩展MutableCollection 并实现您自己的可变映射方法来转换您的数组:

    extension MutableCollection {
        mutating func mutableMap(_ transform: (Element) throws -> Element) rethrows {
            var index = startIndex
            for element in self {
                self[index] = try transform(element)
                formIndex(after: &index)
            }
        }
    }
    

    用法:

    var receivedRates = [1.1, 1.6, 2.0, 1.3]
    receivedRates.mutableMap { $0 * 2.5 }
    print(receivedRates)    // [2.75, 4, 5, 3.25]
    

    在你的情况下:

    if let value = Double(inputTextField.text!) {
        receivedRates.mutableMap { $0 * value }
    }
    

    【讨论】:

      【解决方案2】:
      let newValue = Double(i)*Double(Int(inputTextField.text!)!)
      

      此处的强制解包 (!) 是一个警告标志,并且很可能在您的应用运行时容易中断。

      由于inputTextField 实例的text 属性是可选的,因此在尝试在尝试 初始化中使用它之前,您应该确保安全打开它对于Double 实例。此外,尝试初始化的结果也是如此(这也是可选的)。

      您可以实现这种双重安全展开逻辑,例如使用可选绑定和OptionalflatMap(...) 方法;之后您可以使用例如map 更新 receivedRates 数组的值:

      var receivedRates = [1.1, 1.6, 2.0, 1.3]
      
      if let rateFactor = inputTextField.text.flatMap(Double.init) {
          receivedRates = receivedRates.map { $0 * rateFactor }
      }
      

      或者,元素突变到位(我认为没有理由不在这里使用for .. in 循环):

      if let rateFactor = inputTextField.text.flatMap(Double.init) {
          for idx in receivedRates.indices {
              receivedRates[idx] *= rateFactor
          }
      }
      

      请注意,如果text 属性是nil,或者如果它对Double 实例的初始化失败,则数组将不会被更新(这种情况可以在else 子句中专门处理到上面的if 声明)。

      【讨论】:

        【解决方案3】:

        您想将数组中的所有项目与文本字段的双精度值相乘。

        在 Swift 中一个非常合适的方式是map

        var receivedRates = [1.1, 1.6, 2.0, 1.3]
        
        receivedRates = receivedRates.map{ $0 * Double(inputTextField.text!)! }
        

        或者,您可以枚举索引并更新适当的值

        receivedRates.indices.forEach{ receivedRates[$0] *= Double(inputTextField.text!)! }
        

        我怀疑您是否真的想先将文本转换为Int(丢失小数部分),然后再转换为Double,当然您应该安全地打开选项。

        【讨论】:

        • map 比 for 循环快得多
        • 我想将它们全部设置为零,它有关于“上下文类型”的错误消息,然后在“修复”中插入下划线。编辑:我通过指定“$ 0 * 0”解决了它。有点奇怪,但没关系
        【解决方案4】:

        可以使用map 代替for-in 循环,这样更快,但你必须尽可能避免使用强制展开选项(!),例如如下:

        func updateRates(_ receivedRates: inout [Double], by text: String?) -> Bool {
            guard text != nil, let inputValue = Double(text!) else { return false }
        
            receivedRates = receivedRates.map{ $0 * inputValue }
            return true
        }
        

        用法:

            var receivedRates: [Double] = [1.1, 1.6, 2.0, 1.3]
            if updateRates(&receivedRates, by: inputTextField.text) {
                print(receivedRates)
            }
        

        另一个优点是您使用引用参数inout 来更新原始receivedRates 数组

        【讨论】:

          【解决方案5】:

          你可以使用.map函数

          循环遍历一个集合并对每个元素应用相同的操作 在集合中。

          receivedRates = receivedRates.map{ $0 * Double(inputTextField.text!)!}
          

          参考:Higher Order Functions

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2016-08-17
            • 2019-11-05
            • 2018-02-19
            • 2020-03-28
            • 2014-07-15
            • 2012-06-09
            • 1970-01-01
            相关资源
            最近更新 更多