I've created a class which contains all optional properties. I'm trying to create a computed var
that returns all non-nil properties of the object.
[<array of stuff>].flatMap{ $0 }
seemed like the obvious choice, but when I tinker with it in Playground, it still returns an array containing nil
values.
Here are the various iterations of what I've tried to get an array of non-nil properties of my class:
Let's say I declare my object like so:
let lastSearch = LastSearch(startDate: startDate, endDate: endDate, minMagnitude: 1.0, maxMagnitude: 5.0, minLongitude: nil, maxLongitude: nil, minLatitude: nil, maxLatitude: nil, minDepth: nil, maxDepth: nil)
Attempt #1:
Within my class, I'm trying to create a nonNilProperties
computed variable:
var nonNilProperties: Any {
return [startDate, endDate, minMagnitude, maxMagnitude, minLongitude, maxLongitude, minLatitude, maxLatitude, minDepth , maxDepth].flatMap{ $0 } as Any
}
This is what prints in the console when I print lastSearch.nonNilProperties
:
[Optional(2015-10-01 13:23:32 +0000), Optional(2015-10-07 01:43:59 +0000), Optional(1.0), Optional(5.0), nil, nil, nil, nil, nil, nil]
Attempt #2:
If I tack on as Any
after each property, it quells compiler warnings and the populated values don't print with "Optional" in front of them, but it still has null
values:
var nonNilProperties: Any {
return [startDate as Any, endDate as Any, minMagnitude as Any, maxMagnitude as Any, minLongitude as Any, maxLongitude as Any, minLatitude as Any, maxLatitude as Any, minDepth as Any, maxDepth as Any].flatMap{ $0 } as [AnyObject]
}
This is what prints in the console when I print it:
[2015-10-01 13:23:32 +0000, 2015-10-07 01:43:59 +0000, 1, 5, <null>, <null>, <null>, <null>, <null>, <null>]
Thank you for reading. I welcome your suggestions. Here's what the class looks like:
class LastSearch {
private var startDate: Date?
private var endDate: Date?
private var minMagnitude: Double?
private var maxMagnitude: Double?
private var minLongitude: Double?
private var maxLongitude: Double?
private var minLatitude: Double?
private var maxLatitude: Double?
private var minDepth: Double?
private var maxDepth: Double?
private var nonNilProperties: Any {
return [startDate as Any, endDate as Any, minMagnitude as Any, maxMagnitude as Any, minLongitude as Any, maxLongitude as Any, minLatitude as Any, maxLatitude as Any, minDepth as Any, maxDepth as Any].flatMap{ $0 } as Any
}
init(startDate: Date?, endDate: Date?,
minMagnitude: Double?, maxMagnitude: Double?,
minLongitude: Double?, maxLongitude: Double?,
minLatitude: Double?, maxLatitude: Double?,
minDepth: Double?, maxDepth: Double?) {
// Dates
self.startDate = startDate
self.endDate = endDate
// Magnitude Values
self.minMagnitude = minMagnitude
self.maxMagnitude = maxMagnitude
// Geographic Coordinates
self.minLongitude = minLongitude
self.maxLongitude = maxLongitude
self.minLatitude = minLatitude
self.maxLatitude = maxLatitude
// Depth Values
self.minDepth = minDepth
self.maxDepth = maxDepth
}
}
One solution is to explicitly create a new array of type [Any]
and only add the property to the array if it is not nil
.
public var nonNilProperties: [Any] {
let allProperties: [Any?] = [startDate, endDate, minMagnitude, maxMagnitude, minLongitude, maxLongitude, minLatitude, maxLatitude, minDepth, maxDepth]
var output = [Any]()
for property in allProperties {
if let nonNilProperty = property {
output.append(nonNilProperty)
}
}
return output
}
Or you can use flatMap
which is closer to your original solution (credit to @Leo Dabus)
public var nonNilProperties: [Any] {
return ([startDate, endDate, minMagnitude, maxMagnitude, minLongitude, maxLongitude, minLatitude, maxLatitude, minDepth, maxDepth] as [Any?]).flatMap { $0 }
}
Test case:
let lastSearch = LastSearch(startDate: Date(), endDate: Date(), minMagnitude: 1.0, maxMagnitude: 5.0, minLongitude: nil, maxLongitude: nil, minLatitude: nil, maxLatitude: nil, minDepth: nil, maxDepth: nil)
print(lastSearch.nonNilProperties)
Output:
[2017-11-26 02:00:13 +0000, 2017-11-26 02:00:13 +0000, 1.0, 5.0]
This works, but it's a little awkward. Depending on your exact situation, there is probably a better way to structure your data.