Swift 4中使用SwiftyJSON对比数组并合并匹配值的问题
问题分析与解决方案
你遇到的问题其实是对SwiftyJSON的merge(with:)方法理解有误~这个方法是用来合并两个JSON对象的键值对的,比如把一个对象的属性合并到另一个对象里,而不是用来向数组中添加元素。所以你每次调用merge,都会把新的json_p覆盖到json_cat_array里,最后自然只剩最后一个匹配的对象啦。
正确的做法:用数组收集匹配项
我们需要把目标容器定义成一个JSON数组,然后把符合条件的对象添加到数组中,而不是用merge。同时还要注意避免强制解包string!,防止因为数据异常导致崩溃。
这里给你两种可行的写法:
写法1:用Swift数组存储JSON对象
import SwiftyJSON // 示例JSON数组(假设你从URL获取的是这个格式) let json_cat: JSON = [ ["name": "aaa", "surname": "aaa-1", "grade": "aaa-2"], ["name": "bbb", "surname": "bbb-1", "grade": "bbb-2"], ["name": "ccc", "surname": "ccc-1", "grade": "ccc-2"] ] let arraytest: [String] = ["aaa", "ccc", "ddd"] var resultArray: [JSON] = [] // 定义为JSON类型的数组 json_cat.forEach { (_, jsonItem) in // 安全获取name值,避免强制解包崩溃 if let name = jsonItem["name"].string, arraytest.contains(name) { resultArray.append(jsonItem) } } // 如果你需要把结果转换成SwiftyJSON的JSON对象(比如后续要序列化输出) let resultJSON = JSON(resultArray) print(resultJSON)
写法2:直接用SwiftyJSON的JSON数组类型
如果你更习惯全程用SwiftyJSON的JSON对象来操作,可以这样写:
import SwiftyJSON let json_cat: JSON = [ ["name": "aaa", "surname": "aaa-1", "grade": "aaa-2"], ["name": "bbb", "surname": "bbb-1", "grade": "bbb-2"], ["name": "ccc", "surname": "ccc-1", "grade": "ccc-2"] ] let arraytest: [String] = ["aaa", "ccc", "ddd"] var resultJSON = JSON([]) // 初始化一个空的JSON数组 json_cat.forEach { (_, jsonItem) in if let name = jsonItem["name"].string, arraytest.contains(name) { // 先取出数组,添加元素后重新赋值 if var array = resultJSON.array { array.append(jsonItem) resultJSON = JSON(array) } } } print(resultJSON)
为什么之前的代码只合并了一个值?
再强调下:merge(with:)的作用是把一个JSON对象的键值对合并到另一个JSON对象中,比如:
var obj1 = JSON(["a": 1, "b": 2]) let obj2 = JSON(["b": 3, "c": 4]) try! obj1.merge(with: obj2) // 结果obj1变成 {"a":1, "b":3, "c":4}
它不是用来向数组中追加元素的,所以你之前的循环里每次merge都会覆盖掉json_cat_array的内容,最后就只剩最后一个匹配的对象了。
内容的提问来源于stack exchange,提问作者SNos
相关产品推荐
相关产品推荐

