Swift - 使用 swiftyJSON 根据字典中的值查找字典数组的索引
Posted
技术标签:
【中文标题】Swift - 使用 swiftyJSON 根据字典中的值查找字典数组的索引【英文标题】:Swift - Find the index of an array of dictionaries based on the value in the dictionaries using swiftyJSON 【发布时间】:2015-03-24 10:17:17 【问题描述】:我对编程很陌生,更不用说 Swift 了。我从以前的编程尝试中了解了一些概念,因此我比以往任何时候都走得更远。如果我不清楚我需要什么,我深表歉意。
我正在提取警报列表的 JSON 数据,并尝试使用 swiftyJSON 解析数据,我认为这可以解决问题,但我遇到了尝试从数组中的某些字典中获取一些数据的障碍, 不幸的是,在这个数组中的字典里面是电子邮件地址的位置,不同的字典在彼此之间使用相似的键。
我将向您展示我的结构、函数和 JSON 数据。请帮我获取电子邮件地址、服务 - 它的 ID 和标签。此外,显示的数据中可能存在不止一项服务,我需要捕获所有服务。
这是 JSON 数据:
"hasNext": false,
"data": [
"status": [
1,
"READ"
],
"resolutionStatus": [
0,
"OPEN"
],
"description": "There is some description here",
"title": "Some Activity",
"entities": [
"view_name": "audits",
"type": "link",
"parameters":
"orgUnit": "/"
,
"label": "/"
,
"type": "user",
"id": "hidden@hidden.com",
"label": "hidden@hidden.com"
,
"type": "service",
"id": 6666,
"label": "someService"
,
"type": "service",
"id": 7777,
"label": "anotherService"
],
"stories": [
5
],
"date": "2014-12-10T23:46:28.067000Z",
"audits": [
"ljBhqKQVOF9w",
"pISQyT9iy9w",
"oynGf2_CIw"
],
"_id": "54fdad0dfd",
"id": [
14683,
"ALERT_SOME_ACTIVITY"
],
"severity": [
5,
"HIGH"
]
这是我的结构:
struct AlertModel: Printable
let alertUser: String?
let alertService: String?
let alertTitle: String?
let alertReadStatus: String?
let alertResolutionStatus: String?
let alertDescription: String?
let alertEntities: Array <String> = []
let alertDate: String?
let alertAudits: Array <String> = []
let alertId: String?
let
alertSeverity: String?
// change description to print to console
var description: String
return "User: \(alertUser)\nService: \(alertService)\nTitle: \(alertTitle!)\nRead Status: \(alertReadStatus!)\nResolution Status: \(alertResolutionStatus!)\nDescription: \(alertDescription!)\nDate: \(alertDate!)\nAlert ID: \(alertId!)\nSeverity: \(alertSeverity!)\n******************************************\n"
init(alertUser: String?, alertService: String?, alertTitle: String?, alertReadStat
us: String?, alertResolutionStatus: String?, alertDescription: String?/*, alertEntities: Array<String>*/, alertDate: String?/*, alertAudits: Array<String>*/, alertId: String?, alertSeverity: String?)
self.alertUser = alertUser
self.alertService = alertService
self.alertTitle = alertTitle
self.alertReadStatus = alertReadStatus
self.alertResolutionStatus = alertResolutionStatus
self.alertDescription = alertDescription
//self.alertEntities = alertEntities
self.alertDate = alertDate
//self.alertAudits = alertAudits
self.alertId = alertId
self.alertSeverity = alertSeverity
功能如下:
let jsonAlert = JSON(data: jsonAlertObject)
if let alertArray = jsonAlert["data"].array
var alerts = [AlertModel]()
for alertDict in alertArray
let alertTitle: String? = alertDict["title"].stringValue
let alertReadStatus: String? = alertDict["status"][1].stringValue
let alertResolutionStatus: String? = alertDict["resolutionStatus"][1].stringValue
let alertDescription: String? = alertDict["description"].stringValue
let alertDate: String? = alertDict["date"].stringValue
let alertId: String? = alertDict["_id"].stringValue
// Need to grab the type and label from each dictionary in the array of entities
let alertEntitiesArray: Array? = alertDict["entities"].arrayObject
var arrayIndex = 0
var entitiesDict = ["" : ""]
while arrayIndex < alertEntitiesArray?.count
entitiesDict[alertDict["entities"][arrayIndex]["type"].stringValue] = alertDict["entities"][arrayIndex]["label"].stringValue
arrayIndex++
let alertService: String? = entitiesDict["service"]
let alertUser: String? = entitiesDict["user"]
let alertSeverity: String? = alertDict["severity"][1].stringValue
let alert = AlertModel(alertUser: alertUser, alertService: alertService, alertTitle: alertTitle, alertReadStatus: alertReadStatus, alertResolutionStatus: alertResolutionStatus, alertDescription: alertDescription, alertDate: alertDate, alertId: alertId, alertSeverity: alertSeverity)
alerts.append(alert)
var alertsDictionaryByID = [alertId!: alert]
println(alerts)
如您所见,JSON 数据有几个层次。我可以毫无问题地获取数据并将其提取出来。问题是“实体”数组中可能并不总是包含相同的数据。我有多个服务,它可能没有电子邮件地址,对于数组的第一个值,它可能有一组完全不同的数据。
我正在尝试获取电子邮件地址。如果我能找到一种方法来像字典数据一样搜索“用户”,然后当找到它时,它将返回数组索引值以便能够直接引用它,因为我永远不会知道索引号是用户值的一部分.
我希望我的理解足够清楚,有人可以帮助我。 --- 我的下一步将使用每个单独的警报填充一个 listView。
【问题讨论】:
【参考方案1】:我也在使用 SwiftyJSON,但使用 NSURLConnection 很简单。喜欢这种方法。
//MARK: - NSURLConnection Delegate methods
var responseData : NSMutableData = NSMutableData()
func connection(connection: NSURLConnection!, didReceiveResponse response: NSURLResponse!)
self.responseData.length = 0
func connection(connection: NSURLConnection!, didReceiveData data: NSData!)
self.responseData.appendData(data)
func connectionDidFinishLoading(connection: NSURLConnection!)
if let responseDatas = responseData as NSData?
if let jsonResult : NSDictionary = NSJSONSerialization.JSONObjectWithData(responseDatas, options: NSJSONReadingOptions.MutableContainers, error: nil) as NSDictionary?
if let dataArray = jsonResult.valueForKeyPath("data") as? NSArray
if let entitiesArray = dataArray.valueForKeyPath("entities") as? NSArray
if let firstArray = dataArray[0]
// access your viewName and types here
// Like this method, convert all your parameters and access it.
else
// Do something here
else
// Do something here
else
// Do something here
func connection(connection: NSURLConnection!, didFailWithError error: NSError!)
// Do something here
【讨论】:
感谢您的回复。我尝试添加它,但在最后一个 if-let 语句 '1.常量“firstEntitiesArray”推断为“AnyObject”类型,这可能是意外的。这个指向 firstArray。 '2。条件绑定中的绑定值必须是可选类型。这个指向dataArray [0]。'你能帮我理解最后一个if-let语句如何帮助我找到我正在寻找的键\值吗?如果没有 swiftyJSON,这似乎很简单,但正如我所说,我还是新手,所以我可能无法推断出你所期望的我所知道的东西。 你能帮我理解最后一个 if-let 语句如何帮助我找到我正在寻找的键\值吗?如果没有 swiftyJSON,这似乎很简单,但正如我所说,我还是新手,所以我可能无法推断出你所期望的我所知道的东西。【参考方案2】:我最终发现 SwiftyJSON 和 Alamofire 可以极大地帮助网络和 JSON 序列化。
就数组中字典的问题而言,我最终创建了一个函数,该函数遍历实体数组,分别查看每个字典,然后根据 key="type" 执行 Switch 语句以确定它是否是“用户”字典或“服务”字典,然后将“类型”值(表示它是用户还是服务)与“标签”的值(用户名或服务名称)结合起来,并创建一个新的字典,然后我可以引用它来放回我的数据模型中。
class func retrieveDataFromEntitiesArray (alertDict: JSON) -> (entitesDict: Dictionary<String, String>, servicesArray: [String])
// Need to create an array object, instead of a JSON object, of the entities array to be able to get a count to run the while against.
var arrayIndex = 0
var entitiesDict: Dictionary<String, String> = [:]
var alertEntitiesArray = alertDict.arrayObject
var servicesArray = [String]()
while arrayIndex < alertEntitiesArray?.count
var dictKey = alertDict[arrayIndex]["type"].string
switch (dictKey!)
case "user":
entitiesDict[alertDict[arrayIndex]["type"].stringValue] = alertDict[arrayIndex]["label"].stringValue
case "service":
servicesArray.append(alertDict[arrayIndex]["label"].stringValue)
case "policyRule":
entitiesDict[alertDict[arrayIndex]["type"].stringValue] = alertDict[arrayIndex]["label"].stringValue
default:
println("Nothing Here")
arrayIndex++
return (entitiesDict, servicesArray)
【讨论】:
以上是关于Swift - 使用 swiftyJSON 根据字典中的值查找字典数组的索引的主要内容,如果未能解决你的问题,请参考以下文章
Swift 2 + SwiftyJSON:使用未解决的标识符错误
swift、Alamofire、SwiftyJSON:如何解析 arrayObject
“当前 SwiftyJSON(通过 Swift 3.0.2)无法使用 Swift 3.1 导入”的原因是啥