我希望能够初始化一个能够[7]
能够保存类似于以下信息的空数组结构:
.append()
这是一个字典数组数组的数据类型吗?我希望能够通过var locations = [
["title": "New York, NY", "latitude": 40.713054, "longitude": -74.007228],
["title": "Los Angeles, CA", "latitude": 34.052238, "longitude": -118.243344],
["title": "Chicago, IL", "latitude": 41.883229, "longitude": -87.632398]
]
访问title
,latitude
和longitude
并且我从未使用过类似的内容,因此我不确定如何初始化和location
答案 0 :(得分:1)
是的,它是一个字典数组,但字典值是String
或Double
类型,因此为了适应这两个值,字典类型将是{{1 }}
如果您明确地为location变量的类型转换(而不是推断),那么它将是:
<String: Any>
要访问数组中的值,您可以使用索引下标,其中为该位置的字典索引传入var locations: [Dictionary<String, Any>] = ...
:
Int
您可以深入挖掘第二个下标,访问字典键的值:
let firstLocation = locations[0]
// firstLocation: [String: Any]
// firstLocation -> [ "title": "New York, NY", "latitude": 40.713054, "longitude": -74.007228]
要访问基础字符串类型,您需要从let firstLocationTitle = locations[0]["title"]
// firstLocationTitle: Any?
// firstLocationTitle -> New York, NY
let message = "I'm in" + firstLocationTitle
// fails because operator '+' cannot be applied to operands of type 'String' and 'Any?'
投射到Any?
:
String
要附加新位置,只需要使用相同的类型,此处就可以将波士顿词典添加到位置:
let firstLocationTitle = locations[0]["title"] as! String
// firstLocationTitle: String
// firstLocationTitle -> New York, NY
let message = "I'm in" + firstLocationTitle
// message -> "I'm in New York, NY"
答案 1 :(得分:1)
您的结构是一系列词典:[[String : Any]]
。
正如@Hamish在评论中建议的那样,您可以更好地将数据存储为一系列结构。
以下是一种可能的实施方式:
struct Location: CustomStringConvertible {
var title: String
var latitude: Double
var longitude: Double
var description: String { return "(title: \(title), latitude: \(latitude), longitude: \(longitude))"}
}
var locations = [
Location(title: "New York, NY", latitude: 40.713054, longitude: -74.007228),
Location(title: "Los Angeles, CA", latitude: 34.052238, longitude: -118.243344),
Location(title: "Chicago, IL", latitude: 41.883229, longitude: -87.632398)
]
// Append a new location...
locations.append(Location(title: "Boston, MA", latitude: 42.3601, longitude: -71.0589))
print(locations)
[(title: New York, NY, latitude: 40.713054, longitude: -74.007228), (title: Los Angeles, CA, latitude: 34.052238, longitude: -118.243344), (title: Chicago, IL, latitude: 41.883229, longitude: -87.632398), (title: Boston, MA, latitude: 42.3601, longitude: -71.0589)]
func lookUp(title: String, in locations: [Location]) -> [Location] {
return locations.filter { $0.title.range(of: title) != nil }
}
print(lookUp(title: "CA", in: locations))
[(title: Los Angeles, CA, latitude: 34.052238, longitude: -118.243344)]
print(lookUp(title: "Chicago", in: locations))
[(title: Chicago, IL, latitude: 41.883229, longitude: -87.632398)]
答案 2 :(得分:1)
以下是@vacawama答案的Dictionary
版本。它可以更好地(或更糟)适合某些用例。
此版本有一些值得注意的改进:
find()
执行得非常差。struct
在性能方面的行为类似于class
(较慢)。您的问题并未在struct
。首先创建一个表示坐标的结构。
struct Coordinate {
/// Latitude in decimal notation
let latitude: Double
/// Longitude in decimal notation
let longitude: Double
}
然后创建空集合(根据您的问题)
/// Empty mapping of location string to latitude-longitude
var coordinates = [String: Coordinate]()
以下是填充字典的一种方法示例
/// Populate the locations
coordinates["New York, NY"] = Coordinate(latitude: 40.713054, longitude: -74.007228)
coordinates["Los Angeles, CA"] = Coordinate(latitude: 40.713054, longitude: -74.007228)
coordinates["Chicago, IL"] = Coordinate(latitude: 40.713054, longitude: -74.007228)
示例输出:
print(coordinates["New York, NY"] ?? "Unknown Location”)
> "Coordinates(latitude: 40.713054, longitude: -74.007227999999998)”
就是这样!
enum
上面应该回答原始问题,但是Swift允许使用类型系统更有趣的方法。
我们保证Coordinate
是一对Double
个数字,真棒!但是,无法保证位置的完整性。稍后您可能会意外键入coordinates[“New york, NY”]
。这将失败,因为“约克”是小写的! (以及目前发布的其他答案)。这是枚举:
enum Location: String {
case NY_NewYork = "New York, NY"
case CA_LosAngeles = "Los Angeles, CA"
case IL_Chicago = "Chicago, IL"
}
并相应地更改字典键和用法
/// Empty mapping of location string to latitude-longitude
var coordinates = [Location: Coordinate]()
/// Populate the locations
coordinates[.NY_NewYork] = Coordinate(latitude: 40.713054, longitude: -74.007228)
coordinates[.CA_LosAngeles] = Coordinate(latitude: 40.713054, longitude: -74.007228)
coordinates[.IL_Chicago] = Coordinate(latitude: 40.713054, longitude: -74.007228)
我们仍然拥有原始的“纽约,纽约”标题,但它静态地表示为值Location.NY_NewYork
。这意味着编译器将捕获您可能犯的任何错误!
还有一件事:现在该位置是一个静态常量值,我们实际上可以将它放回struct
内而不会产生可怕的堆分配! (struct值将是对枚举值的引用。)
这是最终版本:
enum Location: String {
case NY_NewYork = "New York, NY"
case CA_LosAngeles = "Los Angeles, CA"
case IL_Chicago = "Chicago, IL"
}
struct Coordinate {
/// The logical name of the location referenced by this coordinate
let location: Location
/// Latitude in decimal notation
let latitude: Double
/// Longitude in decimal notation
let longitude: Double
}
/// Empty mapping of location string to latitude-longitude
var coordinates = [Location: Coordinate]()
/// Populate the locations
coordinates[.NY_NewYork] = Coordinate(location: .NY_NewYork, latitude: 40.713054, longitude: -74.007228)
coordinates[.CA_LosAngeles] = Coordinate(location: .CA_LosAngeles, latitude: 40.713054, longitude: -74.007228)
coordinates[.IL_Chicago] = Coordinate(location: .IL_Chicago, latitude: 40.713054, longitude: -74.007228)
// or if initializing from a data source, something like...
// if let loc = Location(rawValue: "Chicago, IL") {
// coordinates[loc] = Coordinate(location: loc, latitude: 40.713054, longitude: -74.007228)
// }
输出
print(coordinates[Location.NY_NewYork] ?? "uknown”)
> "Coordinate(location: Location.NY_NewYork, latitude: 40.713054, longitude: -74.007227999999998)”
酷!现在我们拥有完美的类型安全性,保持位置标题的便利性以及非常高性能的架构。
这使得Swift成为iOS的特殊工具。
答案 3 :(得分:0)
var locations = [
["title": "New York, NY", "latitude": 40.713054, "longitude": -74.007228],
["title": "Los Angeles, CA", "latitude": 34.052238, "longitude": -118.243344],
["title": "Chicago, IL", "latitude": 41.883229, "longitude": -87.632398]
]
for(loc) in locations {
if let title = loc["title"] as? String, let lat = loc["latitude"] as? Double, let lon = loc["longitude"] as? Double {
print("title: \(title), latitude:\(lat), longitude:\(lon)")
}
}
答案 4 :(得分:0)
最好使用带有元组的 字典。这样你就可以确保你拥有独特的钥匙。
myCities["New York, NY"] = (40.713054,-74.007228)
myCoordinates = myCities["New York, NY"]?
print(String(describing: myCoordinates?.0))
print(String(describing: myCoordinates?.1))
myCoordinates = myCities["Los Angeles, CA"]
print(String(describing: myCoordinates?.0))
print(String(describing: myCoordinates?.1))
键(字符串类型)是城市名称,元组(两个浮点类型)是您的经度/纬度值。
Optional(40.7130547)
Optional(-74.007225)
nil
nil
此代码生成以下控制台输出:
{{1}}