我已从服务器收到此响应,并且我确信必须有一种更有效的方法将其转换为对象。
我有以下回应:
[
id=2997,rapidViewId=62,state=ACTIVE,name=Sprint7,startDate=2018-11-20T10:28:37.256Z,endDate=2018-11-30T10:28:00.000Z,completeDate=<null>,sequence=2992,goal=none
]
如何以最简单的方式将其很好地转换为格式正确的快速对象?
这是我的尝试,仅能给我带来Sprint价值
if sprintJiraCustomField.count > 0 {
let stringOutput = sprintJiraCustomField.first?.stringValue // convert output to String
let name = stringOutput?.components(separatedBy: "name=") // get name section from string
let nameFieldRaw = name![1].components(separatedBy: ",") // split out to the comma
let nameValue = nameFieldRaw.first!
sprintDetail = nameValue// show name field
}
答案 0 :(得分:1)
不知道您想要什么格式,但是下面的代码将生成一个元组(键,值)数组,但是所有值都是字符串,因此我猜想之后需要再次转换
let items = stringOutput.components(separatedBy: ",").compactMap( {pair -> (String, String) in
let keyValue = pair.components(separatedBy: "=")
return (keyValue[0], keyValue[1])
})
答案 1 :(得分:0)
这是减少工作:
let keyValueStrings = yourString.components(separatedBy: ",")
let dictionary = keyValueStrings.reduce([String: String]()) {
(var aggregate: [String: String], element: String) -> [String: String] in
let elements = element.componentsSeparatedByString("=")
let key = elements[0]
// replace nil with the value you want to use if there is no value
let value = (elements.count > 1) ? elements[1] : nil
aggregate[key] = value
return aggregate
}
这是一种实用的方法,但是您可以使用for迭代来实现相同的目的。 因此,您可以使用Swift的基本映射方式。例如,您将拥有自定义对象结构。首先,您将向其添加一个init方法。然后像这样映射您的对象:
init(with dictionary: [String: Any]?) {
guard let dictionary = dictionary else { return }
attribute = dictionary["attrName"] as? String
}
let customObjec = CustomStruct(dictionary: dictionary)
答案 2 :(得分:0)
我们已经有一些建议,首先在每个逗号处分割字符串,然后在等号处分割每个部分。这很容易编写代码,并且效果很好,但是效率不高,因为每个字符必须多次检查。使用Scanner
编写适当的解析器同样容易,但是运行起来会更快。
基本上,扫描程序可以检查给定的字符串是否在当前位置,或者为您提供子字符串,直到下一次出现分隔符为止。
该算法将具有以下步骤:
=
。这是关键=
,
或]
。这就是价值,
,请消耗掉它并继续执行步骤3 ]
。可悲的是,Scanner
API并不十分友好。只需很小的扩展,它就更容易使用:
extension Scanner {
func scanString(_ string: String) -> Bool {
return scanString(string, into: nil)
}
func scanUpTo(_ delimiter: String) -> String? {
var result: NSString? = nil
guard scanUpTo(delimiter, into: &result) else { return nil }
return result as String?
}
func scanUpTo(_ characters: CharacterSet) -> String? {
var result: NSString? = nil
guard scanUpToCharacters(from: characters, into: &result) else { return nil }
return result as String?
}
}
有了这个,我们可以编写如下的解析函数:
func parse(_ list: String) -> [String: String]? {
let scanner = Scanner(string: list)
guard scanner.scanString("[") else { return nil }
var result: [String: String] = [:]
let endOfPair: CharacterSet = [",", "]"]
repeat {
guard
let key = scanner.scanUpTo("="),
scanner.scanString("="),
let value = scanner.scanUpTo(endOfPair)
else {
return nil
}
result[key] = value
} while scanner.scanString(",")
guard scanner.scanString("]") else { return nil }
return result
}