【问题标题】:Convert loop into swift higher order function将循环转换为快速的高阶函数
【发布时间】:2019-02-01 08:47:45
【问题描述】:

我正在用 Swift 4.2 编写一个 iOS 应用程序 我正在遍历 array 1 并对其 one 元素 进行更改并将这些元素添加到 array 2

数组:

let array:[model] = []
let array2:[model] = []

这个数组的模型是:

class model: NSObject {
    var id:Int = 0
    var name:String=""
    var isChecked:Bool=false
}

功能:

    func customCheckboxValueChangedWithID(_ id: Int, isChecked: Bool) {
array2.removeAll()
            //TODO, use sugar syntax/higher order function for this loop:
            for element in array{
                if(element.id==id){
                    element.isChecked=isChecked
if(element.isChecked){
array2.append(element)
}
                }
            }
            reloadCollectionView()
        }

如何将其转换为 swift 高阶函数,如 mapflatMap 等?

【问题讨论】:

  • 作为一个快速的附带问题... Model 是一个类有什么理由吗? (还有一个是 NSObject)?标准的快速方法是从结构开始。只在需要时才去上课。
  • 喜欢numbers.forEach({ if $0.id == id { $0.isChecked = isChecked } })这个?
  • 正确。将删除子类化并使其成为结构
  • @SPatel 如果我需要将此数组设置为另一个数组怎么办?

标签: ios swift


【解决方案1】:

你可以这样做:

array.forEach { if $0.id == id { $0.isChecked.toggle() } }

如果你只想过滤元素,只留下isChecked属性设置为true的元素,你可以使用这个:

let newArray = array.filter { $0.isChecked }

【讨论】:

  • 如果我需要将此数组设置为另一个数组怎么办?
  • 将更改应用到数组后,只需说:let newArray = array。这会将您的数组复制到newArray
  • 我不想操作我当前的数组。我想将具有 isChecked = true 的元素过滤到另一个数组
【解决方案2】:

因为你有一个类数组,这很简单:

let array: [model] = [...]

array.first { $0.id == id }?.isChecked = isChecked

如果您有一个结构数组,则需要更新原始数组或创建一个全新的数组:

var array: [model] = []

// updating element in the original array
if let index = array.index(where: { $0.id == id }) {
   array[index].isChecked = isChecked
}

// updating the whole array
array = array.map {
   guard $0.id == id else { return $0 }
   var element = $0
   element.isChecked = isChecked
   return element 
}

【讨论】:

    【解决方案3】:

    你可以这样重写...

    array.forEach {
        if $0.id == someID { $0.isChecked = isChecked }
    }
    

    这仅在您使用类时才有效。

    如果您切换到使用结构,那么您可以...

    let newArray = array.map {
        if $0.if == someID {
            var theModel = $0
            theModel.isChecked = isChecked
            return theModel
        }
        return $0
    }
    

    【讨论】:

    • 如果我需要将此数组设置为另一个数组怎么办?
    • 抱歉,已更新。 map 函数返回一个新数组。保持原始阵列不变。 (这是您需要注意类的地方。使用类然后即使您创建一个新数组,所有对象也只是对相同对象的引用)
    【解决方案4】:

    如何使用'flatMap'

    这里是操场源码

    //: Playground - noun: a place where people can play
    
    import UIKit
    
    struct model {
        var id:Int = 0
        var name:String=""
        var isChecked:Bool=false
    }
    
    let array:[model] = [model(id: 0, name: "0", isChecked: false),
    model(id: 1, name: "1", isChecked: false),
    model(id: 2, name: "2", isChecked: false),
    model(id: 3, name: "3", isChecked: false),
    model(id: 4, name: "4", isChecked: false),
    model(id: 5, name: "5", isChecked: false),
    model(id: 6, name: "6", isChecked: false)
    ]
    var array2:[model] = []
    
    
    func customCheckboxValueChangedWithID(_ id: Int, isChecked: Bool) {
        array2 = array.flatMap { (ma: model) -> model? in
            var element = ma
    
            if element.id == id {
                element.isChecked = isChecked
                return element
            }
            return nil
        }
    }
    
    
    customCheckboxValueChangedWithID(1, isChecked: true)
    print("array2 : \(array2)")
    

    结果: array2 : [__lldb_expr_53.model(id: 1, name: "1", isChecked: true)]

    【讨论】:

      【解决方案5】:

      您可以使用过滤器

      numbers.forEach({ if $0.id == id { $0.isChecked = isChecked } })(复制了 SPatel 的评论)

      遍历一个集合并返回一个包含满足条件的元素的数组。

      假设我们只需要在下面的数组示例中过滤偶数。传统方法可以是:

      let numbersArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 14, 15]
      
      // The traditional way
      var evenNumArray: [Int] = []
      for number in numbersArray {
        if number % 2 == 0 {
          evenNumArray.append(number)
        }
      }
      // evenNumArray = [2, 4, 6, 8, 10, 14]
      

      相反,让我们使用过滤器来获得相同的结果:

      let numbersArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 14, 15]
      // Filter
      let evenArray = numbersArray.filter { $0 % 2 == 0 }
      

      Simple Higher Order Functions in Swift

      【讨论】:

        【解决方案6】:

        你可以试试这个:

        class MyObj: CustomStringConvertible {
            var id: String
            var isChecked: Bool
        
            init(id: String = "", isChecked: Bool = false) {
                self.id = id
                self.isChecked = isChecked
            }
        
            var description: String {
                return "MyObj(id: \(id), isChecked: \(isChecked)"
            }
        }
        
        let array = [
            MyObj(id: "id1"),
            MyObj(id: "id1", isChecked: true),
            MyObj(id: "id2"),
            MyObj(id: "id3", isChecked: true)
        ]
        
        func customCheckboxValueChanged(_ values: [MyObj], id: String, isChecked: Bool) -> [MyObj] {
            let sameIDModels: [MyObj] = values
                .filter { $0.id == id }
                .map { $0.isChecked = isChecked; return $0 }
        
            return sameIDModels.filter{ $0.isChecked }
        }
        
        let isChecked = true
        let myID = "id1"
        
        print(customCheckboxValueChanged(array, id: myID, isChecked: isChecked))
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-05-20
          • 1970-01-01
          • 1970-01-01
          • 2016-06-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多