避免在 swift 4 中重复代码

avoid repeating code in swift 4

我想创建一个通用函数以避免在使用条件时重复。是否有任何可能的想法来实现这一目标? 谢谢

struct ObjectDataItem {
var name: String
var value: String
}

static func arrayFields(arrayObject: ArrayObject) -> Array<ObjectDataItem> {
    var objectFields = [ObjectDataItem]()

    if let objectCategoryValue = arrayObject.objectCategory {
        let data = [ObjectDataItem(name: ObjectCategoryConstant.objectCategoryKey, value: objectCategory)]
        objectFields.append(contentsOf: data)
    }

    if let objectTypeValue = arrayObject.objectType {
        let data = [ObjectDataItem(name: ObjectTypeConstant.objectTypeKey, value: objectTypeValue)]
        objectFields.append(contentsOf: data)
    }

    if let objectName = arrayObject.objectName {
        let data = [ObjectDataItem(name: ObjectNameConstant.objectNameKey, value: objectName)]
        objectFields.append(contentsOf: data)
    }

    if let countryObjectValue = arrayObject.countryObjectCode {
        let data = [ObjectDataItem(name: countryObjectConstant.countryObjectCodeKey, value: countryObjectValue)]
        objectFields.append(contentsOf: data)
    }

    return objectFields
}

唯一对我有意义的是先创建一个字典:

var dataDictionary: [String: String] = [:]
dataDictionary[ObjectCategoryConstant.objectCategoryKey] = arrayObject.objectCategory
dataDictionary[ObjectCategoryConstant.objectTypeKey] = arrayObject.objectType
dataDictionary[ObjectCategoryConstant.objectNameKey] = arrayObject.objectName
dataDictionary[countryObjectConstant.countryObjectCodeKey] = arrayObject.countryObjectValue

let objectFields = dataDictionary.map { (name, value) in
    ObjectDataItem(name: name, value: countryObjectValue)
}

字典不包含 nil 的值。但是,您会丢失值的顺序(如果它对您很重要)。简化的也不是很大

如果你不介意你的键是你的属性名字的名字,你也可以使用反射像这样:

func arrayFields(arrayObject: ArrayObject) -> Array<ObjectDataItem> {
    var objectFields = [ObjectDataItem]()
    let objectMirror = Mirror(reflecting: arrayObject)
    for child in objectMirror.children {
        let (propertyName, propertyValue) = child
        objectFields.append(ObjectDataItem(name:propertyName!, value: propertyValue as! String))
    }
    return objectFields
}

您可以使用键路径

func arrayFields(arrayObject: ArrayObject) -> Array<ObjectDataItem> {
    var objectFields = [ObjectDataItem]()

    func appendField(key: String, valuePath: KeyPath<ArrayObject, String?>) {
        if let value = arrayObject[keyPath: valuePath] {
            let data = [ObjectDataItem(name: key, value: value)]
            objectFields.append(contentsOf: data)
        }
    }

    appendField(key: ObjectCategoryConstant.objectCategoryKey, valuePath: \ArrayObject.objectCategory)
    appendField(key: ObjectCategoryConstant.objectTypeKey, valuePath: \ArrayObject.objectType)

    return objectFields
}

你可以更进一步,使用字典来查找键,这样最后你只需要传入键路径即可。