reduce 函数正在打印一个空字典 [:]
reduce function is printing an empty dictionary [:]
我在这个 中成功地减少了我的字典键作为伪代码,没有真正的 json 模型。我在上一个问题中完成的目标是 return 只有具有匹配值的键 。所以输出是一个看起来像这样的字典 ["WoW": ["@jade", "@kalel"]
。正是我所需要的。当然可能还有其他比赛,我也想return那些。
现在我有了一个合适的 json 模型,reduce 函数正在打印一个空字典 [:]
。是 .reduce(into: [String:[String]]()
中的类型导致了问题吗?
所有数据都在打印,所以json和模型结构必须正确。
json
[
{
"id": "tokenID-tqkif48",
"name": "@jade",
"game": "WoW",
"age": "18"
},
{
"id": "tokenID-fvkif21",
"name": "@kalel",
"game": "WoW",
"age": "20"
}
]
用户模型
public typealias Users = [UserModel]
public struct UserModel: Codable {
public let name: String
public let game: String
// etc...
enum CodingKeys: String, CodingKey {
case name
case game
// etc...
游乐场
guard let url = Bundle.main.url(forResource: "Users", withExtension: "json") else {
fatalError()
}
guard let data = try? Data(contentsOf: url) else {
fatalError()
}
let decoder = JSONDecoder()
do {
let response = try decoder.decode([UserModel].self, from: data)
for userModel in response {
let userDict: [String:String] = [ userModel.name:userModel.game ]
let reduction = Dictionary(grouping: userDict.keys) { userDict[[=12=]] ?? "" }.reduce(into: [String:[String]](), { (result, element) in
if element.value.count > 1 {
result[element.key] = element.value
}
})
// error catch etc
}
你的代码太复杂了。您可以通过 game
简单地使用
对数组进行分组
let response = try decoder.decode([UserModel].self, from: data)
let reduction = Dictionary(grouping: response, by: {[=10=].game}).mapValues{ usermodel in usermodel.map{ [=10=].name}}
更新 我可能误会了你想要得到的东西。下面还有一个代码,请检查结果并选择一个你想要的。
如果想用reduce(into:updateAccumulatingResult:)
,可以这样写
do {
let response = try decoder.decode([UserModel].self, from: data)
let userArray: [(name: String, game: String)] = response.map {([=10=].name, [=10=].game)}
let reduction = userArray.reduce(into: [String:[String]]()) {result, element in
if !element.game.isEmpty {
result[element.name, default: []].append(element.game)
}
}
print(reduction)
} catch {
print(error)
}
如果您更喜欢 Dictionary
的初始值设定项,这可能有效:
do {
let response = try decoder.decode([UserModel].self, from: data)
let userArray: [(name: String, games: [String])] = response.map {
([=11=].name, [=11=].game.isEmpty ? [] : [[=11=].game])
}
let reduction = Dictionary(userArray) {old, new in old + new}
print(reduction)
} catch {
print(error)
}
双输出:
["@jade": ["WoW"], "@kalel": ["WoW"]]
无论如何,除了 userDict.keys
之外,您组合循环 Dictionary(grouping:)
和 reduce(into:)
的方式使事情变得过于复杂。
ADDITION 当你想获得一个带键的字典作为游戏时:
do {
let response = try decoder.decode([UserModel].self, from: data)
let userArray: [(game: String, name: String)] = response.compactMap {
[=13=].game.isEmpty ? nil : ([=13=].game, [=13=].name)
}
let reduction = userArray.reduce(into: [String:[String]]()) {result, element in
result[element.game, default: []].append(element.name)
}
print(reduction)
} catch {
print(error)
}
或:
do {
let response = try decoder.decode([UserModel].self, from: data)
let userArray: [(game: String, names: [String])] = response.compactMap {
[=14=].game.isEmpty ? nil : ([=14=].game, [[=14=].name])
}
let reduction = Dictionary(userArray) {old, new in old + new}
print(reduction)
} catch {
print(error)
}
输出:
["WoW": ["@jade", "@kalel"]]
我在这个 ["WoW": ["@jade", "@kalel"]
。正是我所需要的。当然可能还有其他比赛,我也想return那些。
现在我有了一个合适的 json 模型,reduce 函数正在打印一个空字典 [:]
。是 .reduce(into: [String:[String]]()
中的类型导致了问题吗?
所有数据都在打印,所以json和模型结构必须正确。
json
[
{
"id": "tokenID-tqkif48",
"name": "@jade",
"game": "WoW",
"age": "18"
},
{
"id": "tokenID-fvkif21",
"name": "@kalel",
"game": "WoW",
"age": "20"
}
]
用户模型
public typealias Users = [UserModel]
public struct UserModel: Codable {
public let name: String
public let game: String
// etc...
enum CodingKeys: String, CodingKey {
case name
case game
// etc...
游乐场
guard let url = Bundle.main.url(forResource: "Users", withExtension: "json") else {
fatalError()
}
guard let data = try? Data(contentsOf: url) else {
fatalError()
}
let decoder = JSONDecoder()
do {
let response = try decoder.decode([UserModel].self, from: data)
for userModel in response {
let userDict: [String:String] = [ userModel.name:userModel.game ]
let reduction = Dictionary(grouping: userDict.keys) { userDict[[=12=]] ?? "" }.reduce(into: [String:[String]](), { (result, element) in
if element.value.count > 1 {
result[element.key] = element.value
}
})
// error catch etc
}
你的代码太复杂了。您可以通过 game
简单地使用
let response = try decoder.decode([UserModel].self, from: data)
let reduction = Dictionary(grouping: response, by: {[=10=].game}).mapValues{ usermodel in usermodel.map{ [=10=].name}}
更新 我可能误会了你想要得到的东西。下面还有一个代码,请检查结果并选择一个你想要的。
如果想用reduce(into:updateAccumulatingResult:)
,可以这样写
do {
let response = try decoder.decode([UserModel].self, from: data)
let userArray: [(name: String, game: String)] = response.map {([=10=].name, [=10=].game)}
let reduction = userArray.reduce(into: [String:[String]]()) {result, element in
if !element.game.isEmpty {
result[element.name, default: []].append(element.game)
}
}
print(reduction)
} catch {
print(error)
}
如果您更喜欢 Dictionary
的初始值设定项,这可能有效:
do {
let response = try decoder.decode([UserModel].self, from: data)
let userArray: [(name: String, games: [String])] = response.map {
([=11=].name, [=11=].game.isEmpty ? [] : [[=11=].game])
}
let reduction = Dictionary(userArray) {old, new in old + new}
print(reduction)
} catch {
print(error)
}
双输出:
["@jade": ["WoW"], "@kalel": ["WoW"]]
无论如何,除了 userDict.keys
之外,您组合循环 Dictionary(grouping:)
和 reduce(into:)
的方式使事情变得过于复杂。
ADDITION 当你想获得一个带键的字典作为游戏时:
do {
let response = try decoder.decode([UserModel].self, from: data)
let userArray: [(game: String, name: String)] = response.compactMap {
[=13=].game.isEmpty ? nil : ([=13=].game, [=13=].name)
}
let reduction = userArray.reduce(into: [String:[String]]()) {result, element in
result[element.game, default: []].append(element.name)
}
print(reduction)
} catch {
print(error)
}
或:
do {
let response = try decoder.decode([UserModel].self, from: data)
let userArray: [(game: String, names: [String])] = response.compactMap {
[=14=].game.isEmpty ? nil : ([=14=].game, [[=14=].name])
}
let reduction = Dictionary(userArray) {old, new in old + new}
print(reduction)
} catch {
print(error)
}
输出:
["WoW": ["@jade", "@kalel"]]