根据条件从 JSON 获取值
Get Values from JSON According to Condition
我在应用程序包中有一个本地 Json 文件。
现有 Json 文件:
[
{
"id": 1001,
"key1": true,
"key2": "key2Value",
},
{
"id": 1002,
"key1": false,
"key2": "key2Value",
},
{
"id": 1003,
"key1": true,
"key2": "key2Value",
},
]
如果 key1
值为 true
,我想遍历 json 并获取 ID。
我这样试过,但出现错误:
let vehicleInfoTest: [Vehicle] = readJSONTest("vehicleInfo.json")
func readJSONTest<T: Codable>(_ named: String) -> T{
let data: Data
let ids: Int
do {
let fileURL = try FileManager.default
.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
.appendingPathComponent("vehicleInfo.json")
data = try Data(contentsOf: fileURL)
// I can successfully get the foo
let foo = try JSONDecoder().decode(T.self, from: data)
// For loop gives an error: For-in loop requires 'Vehicle' to conform to 'Sequence'
for item in foo as! Vehicle{
if item.key1 == true{
ids = item.id
}
}
return foo
} catch {
fatalError("Couldn't find in main bundle.")
}
}
最后ids
应该是这样的:
ids = 1001, 1003
如何获取 ID?
简单
let ids = vehicles.filter { [=10=].key1 }.map { [=10=].id }
而不是您的 for
循环应该可以解决问题 - 但是,这不应该是通用方法的一部分。
要么 readJSONTest
是通用的,要么它知道 Vehicle
的内部结构,但实际上不应该两者都做。
此外,当 key1 已经是非可选 Bool
时,请不要说 x.key1 == true
。
泛型函数中的非泛型代码没有意义。
循环假设T
是一个数组并且类型有一个成员key1
。在循环外过滤数组,使函数throw
func readJSONTest<T: Decodable>(_ named: String) throws -> T {
let fileURL = try FileManager.default
.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
.appendingPathComponent("vehicleInfo.json")
let data = try Data(contentsOf: fileURL)
return try JSONDecoder().decode(T.self, from: data)
}
let vehicleInfoTest: [Vehicle] = try readJSONTest("vehicleInfo.json")
let ids = vehicleInfoTest.lazy.filter{[=10=].key1}.map{[=10=].id}
您的代码有点乱,您有一个通用函数,您尝试将其用作非通用函数,并且其中还有一些其他乱七八糟的东西。由于您首先需要在步骤 1 中调用通用函数,然后在第二步中对结果进行过滤,因此以下代码将为您提供 ID,其中 key1
为 true
let vehicleInfoTest: [Vehicle] = readJSONTest("vehicleInfo.json")
let idValues = vehicleInfoTest.filter({ [=10=].key1 }).map( {[=10=].id })
现在要让它工作,需要清理函数
func readJSONTest<T: Codable>(_ named: String) -> T{
do {
let fileURL = try FileManager.default
.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
.appendingPathComponent(named). //use parameter, not hardcoded string
let data = try Data(contentsOf: fileURL)
return try JSONDecoder().decode(T.self, from: data) // directly return decoded values
} catch {
fatalError("Decoding failed with error \(error)") // More useful error message
}
}
我在应用程序包中有一个本地 Json 文件。
现有 Json 文件:
[
{
"id": 1001,
"key1": true,
"key2": "key2Value",
},
{
"id": 1002,
"key1": false,
"key2": "key2Value",
},
{
"id": 1003,
"key1": true,
"key2": "key2Value",
},
]
如果 key1
值为 true
,我想遍历 json 并获取 ID。
我这样试过,但出现错误:
let vehicleInfoTest: [Vehicle] = readJSONTest("vehicleInfo.json")
func readJSONTest<T: Codable>(_ named: String) -> T{
let data: Data
let ids: Int
do {
let fileURL = try FileManager.default
.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
.appendingPathComponent("vehicleInfo.json")
data = try Data(contentsOf: fileURL)
// I can successfully get the foo
let foo = try JSONDecoder().decode(T.self, from: data)
// For loop gives an error: For-in loop requires 'Vehicle' to conform to 'Sequence'
for item in foo as! Vehicle{
if item.key1 == true{
ids = item.id
}
}
return foo
} catch {
fatalError("Couldn't find in main bundle.")
}
}
最后ids
应该是这样的:
ids = 1001, 1003
如何获取 ID?
简单
let ids = vehicles.filter { [=10=].key1 }.map { [=10=].id }
而不是您的 for
循环应该可以解决问题 - 但是,这不应该是通用方法的一部分。
要么 readJSONTest
是通用的,要么它知道 Vehicle
的内部结构,但实际上不应该两者都做。
此外,当 key1 已经是非可选 Bool
时,请不要说 x.key1 == true
。
泛型函数中的非泛型代码没有意义。
循环假设T
是一个数组并且类型有一个成员key1
。在循环外过滤数组,使函数throw
func readJSONTest<T: Decodable>(_ named: String) throws -> T {
let fileURL = try FileManager.default
.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
.appendingPathComponent("vehicleInfo.json")
let data = try Data(contentsOf: fileURL)
return try JSONDecoder().decode(T.self, from: data)
}
let vehicleInfoTest: [Vehicle] = try readJSONTest("vehicleInfo.json")
let ids = vehicleInfoTest.lazy.filter{[=10=].key1}.map{[=10=].id}
您的代码有点乱,您有一个通用函数,您尝试将其用作非通用函数,并且其中还有一些其他乱七八糟的东西。由于您首先需要在步骤 1 中调用通用函数,然后在第二步中对结果进行过滤,因此以下代码将为您提供 ID,其中 key1
为 true
let vehicleInfoTest: [Vehicle] = readJSONTest("vehicleInfo.json")
let idValues = vehicleInfoTest.filter({ [=10=].key1 }).map( {[=10=].id })
现在要让它工作,需要清理函数
func readJSONTest<T: Codable>(_ named: String) -> T{
do {
let fileURL = try FileManager.default
.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
.appendingPathComponent(named). //use parameter, not hardcoded string
let data = try Data(contentsOf: fileURL)
return try JSONDecoder().decode(T.self, from: data) // directly return decoded values
} catch {
fatalError("Decoding failed with error \(error)") // More useful error message
}
}