J'ai créé une classe qui contient toutes les propriétés facultatives. J'essaye de créer un var
calculé qui renvoie toutes les propriétés non nulles de l'objet.
[<array of stuff>].flatMap{ $0 }
semblait être le choix évident, mais quand je le bricoler dans Playground, il renvoie toujours un tableau contenant des valeurs nil
.
Voici les différentes itérations de ce que j'ai essayé pour obtenir un tableau de propriétés non nulles de ma classe:
Disons que je déclare mon objet comme ceci:
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)
Tentative n ° 1: Dans ma classe, j'essaye de créer une variable calculée nonNilProperties
:
var nonNilProperties: Any {
return [startDate, endDate, minMagnitude, maxMagnitude, minLongitude, maxLongitude, minLatitude, maxLatitude, minDepth , maxDepth].flatMap{ $0 } as Any
}
C'est ce qui s'imprime dans la console lorsque j'imprime 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]
Tentative n ° 2:
Si je cloue sur as Any
après chaque propriété, il réprime les avertissements du compilateur et les valeurs renseignées ne s'impriment pas avec "Facultatif" devant eux, mais il a toujours des valeurs null
:
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]
}
C'est ce qui s'imprime dans la console lorsque je l'imprime:
[2015-10-01 13:23:32 +0000, 2015-10-07 01:43:59 +0000, 1, 5, <null>, <null>, <null>, <null>, <null>, <null>]
Merci pour la lecture. J'apprécie vos suggestions. Voici à quoi ressemble la classe:
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
}
}
3 réponses
Une solution consiste à créer explicitement un nouveau tableau de type [Any]
et à n'ajouter la propriété au tableau que si ce n'est pas 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
}
Ou vous pouvez utiliser flatMap
qui est plus proche de votre solution d'origine (crédit à @Leo Dabus)
public var nonNilProperties: [Any] {
return ([startDate, endDate, minMagnitude, maxMagnitude, minLongitude, maxLongitude, minLatitude, maxLatitude, minDepth, maxDepth] as [Any?]).flatMap { $0 }
}
Cas de test:
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)
Sortie:
[2017-11-26 02:00:13 +0000, 2017-11-26 02:00:13 +0000, 1.0, 5.0]
Cela fonctionne, mais c'est un peu gênant. En fonction de votre situation exacte, il existe probablement une meilleure façon de structurer vos données.
Le premier nonNilProperties n'est pas Any, son [Any] (tableau de any). Et vous n'avez pas besoin de convertir chaque propriété en une, il le fera automatiquement. Deuxièmement, flatMap n'est pas ce dont vous avez besoin. Utilisez la carte. flatMap n'itère pas sur les éléments, mais fonctionne sur l'ensemble du tableau. Voici quelques exemples: http : //sketchytech.blogspot.ru/2015/06/swift-what-do-map-and-flatmap-really-do.html
Comme Leo Dabus l'a souligné dans ses commentaires, avoir les valeurs non nulles par elles-mêmes est inutile si je ne sais pas ce qu'elles sont. Cela dit, voici ce que j'ai finalement fait:
Dans la réponse Charles Prince, j'ai trouvé une méthode pour dérouler les options.
J'ai ajouté cette méthode à ma classe:
func unwrap<T>(_ any: T) -> Any {
let mirror = Mirror(reflecting: any)
guard mirror.displayStyle == .optional, let first = mirror.children.first else {
return any
}
return unwrap(first.value)
}
Ensuite, j'ai créé une var calculée pour renvoyer un Dictionary
de valeurs non nulles, en saisissant des clés et des valeurs en utilisant Mirror
.
var nonNilPropertyDict: [String: Any] {
let keys = Mirror(reflecting: self).children.flatMap { $0.label }
let values = Mirror(reflecting: self).children.flatMap { unwrap($0.value) as! AnyObject }
var dict = Dictionary(uniqueKeysWithValues: zip(keys, values))
var keysToRemove = dict.keys.filter{ dict[$0] is NSNull }
for key in keysToRemove {
dict.removeValue(forKey: key)
}
return dict
}
De nouvelles questions
ios
iOS est le système d'exploitation mobile fonctionnant sur Apple iPhone, iPod touch et iPad. Utilisez cette balise [ios] pour les questions liées à la programmation sur la plate-forme iOS. Utilisez les balises associées [objective-c] et [swift] pour les problèmes spécifiques à ces langages de programmation.