1

I would like to create a generic function to avoid repeating while using conditions. Is there any possible ideas to achieve this? Thanks

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
}
dicle
  • 1,122
  • 1
  • 12
  • 40
  • 1
    What are the methods `. objectCategoryKey` which are put on `String`? – Sulthan Mar 06 '18 at 07:05
  • 1
    Why don't you use a normal `objectFields.append(ObjectDataItem(...))`? Actually you have almost no duplicate code. The code you be probably simplified by changing your data representation. Which is not included in you question. – Sulthan Mar 06 '18 at 07:06
  • hey i have updated now @Sulthan – dicle Mar 06 '18 at 07:09
  • Humm i thought maybe i can have generic func somehow to reduce this if contidions repeading.. @Sulthan – dicle Mar 06 '18 at 07:10

3 Answers3

1

You could use keypaths

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
}

You could go a step further and use a dictionary to lookup the keys, so in the end you would only have to pass in the keypath.

Luke
  • 4,908
  • 1
  • 37
  • 59
0

The only thing that makes sense to me is to create a dictionary first:

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)
}

Dictionary does not contain values that are nil. However, you lose the ordering of values (if it's important for you). The simplification is not very big either.

Sulthan
  • 128,090
  • 22
  • 218
  • 270
  • also in this way again i need to type "ObjectDataItem(name: name, value: arrayObject .countryObjectValue)" this for all .. humm yeah simplification is not big.. – dicle Mar 06 '18 at 07:32
  • @DicleY Simplify your data model instead. – Sulthan Mar 06 '18 at 07:35
0

You can also use reflection if you do not mind your keys to be the names of your property names Something like this:

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
}
Carien van Zyl
  • 2,853
  • 22
  • 30