我的代码中有一个厄运金字塔。
if places.count > 0 {
for i in 0..<places.count {
for j in 0..<places.count {
if let nameI = places[i]["name"] {
if let cityI = places[i]["city"] {
if let nameJ = places[j]["name"] {
if let cityJ = places[j]["city"] {
if let latI = places[i]["lat"] {
if let lonI = places[i]["lon"] {
if let latitudeI = Double(latI) {
if let longitudeI = Double(lonI) {
if let latJ = places[j]["lat"] {
if let lonJ = places[j]["lon"] {
if let latitudeJ = Double(latJ) {
if let longitudeJ = Double(lonJ) {
if(i != j) {
let coordinateI = CLLocation(latitude: latitudeI, longitude: longitudeI)
let coordinateJ = CLLocation(latitude: latitudeJ, longitude: longitudeJ)
let distanceInMeters = coordinateI.distance(from: coordinateJ) // result is in meters
let distanceInMiles = distanceInMeters/1609.344
var distances = [Distance]()
distances.append(Distance(
distanceInMiles: distanceInMiles,
distanceInMeters: distanceInMeters,
places: [
Place(name: nameI, city: cityI, lat: latitudeI, long: longitudeI, coordinate: coordinateI),
Place(name: nameJ, city: cityJ, lat: latitudeJ, long: longitudeJ, coordinate: coordinateJ),
]
))
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
如何避免呢?
我应该遵循一种技巧或规则吗?
在iOS中,我们必须使用大量if-let
。如何避免像我这样?
答案 0 :(得分:1)
这是第一个近似值。如您所见,有很多重复的模式可以提取出来。
for (i, placeDictI) in 0..<places.enumerated() {
guard
let nameI = placeDictI["name"],
let cityI = placeDictI["city"],
let latitudeI = placeDictI["lat"].map(Double.init),
let longitudeI = placeDictI["lon"].map(Double.init),
else { continue }
let coordinateI = CLLocation(latitude: latitudeI, longitude: longitudeI)
let placeI = Place(name: nameI, city: cityI, lat: latitudeI, long: longitudeI, coordinate: coordinateI)
for (j, placeDictJ) in places.enumerated() where i != j {
guard let nameJ = placeDictI["name"],
let cityJ = placeDictI["city"],
let latitudeJ = placeDictI["lat"].map(Double.init),
let longitudeJ = placeDictI["lon"].map(Double.init)
else { continue }
let coordinateJ = CLLocation(latitude: latitudeJ, longitude: longitudeJ)
let placeJ = Place(name: nameJ, city: cityJ, lat: latitudeJ, long: longitudeJ, coordinate: coordinateJ)
let distanceInMeters = coordinateI.distance(from: coordinateJ) // result is in meters // Editor's note: REALLY? I would have thought that a variable called "distanceInMeters" would store volume in litres! Silly me!
let distanceInMiles = distanceInMeters/1609.344
var distances = [Distance]()
distances.append(Distance(
distanceInMiles: distanceInMiles,
distanceInMeters: distanceInMeters,
places: [ placeI, placeJ ]
))
}
}
这是我应用的转换:
places.count > 0
。如果为0,则循环将不执行任何操作。if
语句的块完全包含其父块的情况,我将其替换为guard
。guard
语句合并。Optional.map(_:)
表达式,而不是let
语句中单独的guard
子句i != j
循环上的where
检查更改为for
条件。更改了此模式:
for i in 0..<array.count {
use(array[i])
use(array[i])
use(array[i])
//...
}
为此模式:
for (i, element) in array.enumerated() {
use(element)
use(element)
use(element)
//...
}
由于没有明显的重复情况,这很好地暗示了将字典分解成Place
的字典属于便捷初始化程序,该字典使用了使Place?
无效的字典。更好的是,只需使用Codable系统,然后让编译器为您合成它即可。
答案 1 :(得分:0)
该问题的最新答案
我不会深入探讨已发布的代码块,但是在任何情况下的“厄运金字塔”中,您都可以使用 Guard 语句。您可以找到有关如何实施以及如何避免的详细信息。 检查此媒体链接