简体   繁体   English

在Swift中使用来自json的相同键解码字典

[英]Decode dictionary with identical keys from json in Swift

I have a struct that I describe in a JSON file, say the struct is named Dog我有一个我在 JSON 文件中描述的结构,假设该结构名为Dog

struct Dog {
  var color: UIColor
}

I'm keeping track of my dogs in a dictionary in a JSON file where each dog's name act as an identifier.我在 JSON 文件中的字典中跟踪我的狗,其中每条狗的名字充当标识符。 So I could have the next JSON:所以我可以有下一个 JSON:

"myDogs": {

  "goodBoy": {
    "color": "#000000"
  },

  "veryGoodBoy": {
    "color": "#FFFFFF
  }

}

To descrive my 2 dogs, it being a dictionary I (obviously) want to avoid duplicate keys, so I would expect that when I decode myDogs that is of type [String: Dog] if the JSON has 2 dogs with the same key (name) I would get some error.为了描述我的 2 只狗,它是我(显然)想要避免重复键的字典,所以我希望当我解码[String: Dog]类型的myDogs ,如果 JSON 有 2 只狗具有相同的键(名称) ) 我会得到一些错误。

To my surprise it's not happening, instead it just ignores all the dogs after the first one, ie for this JSON令我惊讶的是,它没有发生,而是忽略了第一个之后的所有狗,即对于这个 JSON

"myDogs": {

  "goodBoy": {
    "color": "#000000"
  },

  "veryGoodBoy": {
    "color": "#FFFFFF
  }

  "goodBoy": {
    "color": "#FF0000"
  }

}

I would get a dictionary with 2 dogs, one name "goodBoy" with black color, and another named "veryGoodBoy" with white color.我会得到一本有 2 只狗的字典,一个叫“goodBoy”,颜色为黑色,另一个叫“veryGoodBoy”,颜色为白色。

Is there a way to raise an exception (or at least log an error) in the decoding stage?有没有办法在解码阶段引发异常(或至少记录错误)?

Thanks in advance.提前致谢。

Edit编辑

Does JSON syntax allow duplicate keys in an object? JSON 语法是否允许对象中的重复键? helps but it doesnt answer my question.有帮助,但它没有回答我的问题。 Basically I'm asking is there a way in Swift to raise an exception in the decoding stage without rewriting JSONDecoder()基本上我问的是 Swift 中是否有一种方法可以在不重写JSONDecoder()的情况下在解码阶段引发异常

Ok so you want to know if there is a way of detecting the duplicate key error with JSONDecoder .好的,所以您想知道是否有办法使用JSONDecoder检测重复键错误。

Honestly I didn't know the answer so I investigated a bit.老实说,我不知道答案,所以我调查了一下。

1. Let's fix your JSON keeping the duplicate key inconsistency 1. 让我们修复您的 JSON 保持重复键不一致

Your input JSON has several errors besides the duplicate key.除了重复键之外,您的输入 JSON 有几个错误。

  1. A JSON should being with { or ] and ending with the same symbol as well JSON 应该带有{]并以相同的符号结尾
  2. There is a missing " at the end of "#FFFFFF “#FFFFFF "的末尾缺少"
  3. There is a missing , at the end of有一个失踪,在结束
  "veryGoodBoy": {
    "color": "#FFFFFF
  }

Let's apply these fixes and we finally get a JSON where the only error is the duplicate key让我们应用这些修复,我们最终得到一个 JSON,其中唯一的错误是重复键

let data = """
{
    "myDogs": {

      "goodBoy": {
        "color": "#000000"
      },

      "veryGoodBoy": {
        "color": "#FFFFFF"
      },

      "goodBoy": {
        "color": "#FF0000"
      }
    }
}
""".data(using: .utf8)!

2. The Codable struct 2. Codable 结构

Now we can define a Codable type (I usually prefer a struct when decoding JSONs) to match the input JSON现在我们可以定义一个Codable类型(我通常在解码 JSON 时更喜欢结构体)来匹配输入 JSON

struct Response: Decodable {

    let myDogs: [String: Dog]

    struct Dog: Decodable {
        let color: String
    }
}

3. Decoding 3.解码

Finally let's try decoding the JSON最后让我们尝试解码 JSON

do {
    let dict = try JSONDecoder().decode(Response.self, from: data)
    print(dict)
} catch {
    print(error)
}

This code runs fine without raising an error.此代码运行良好而不会引发错误。 But (of course) the resulting value has a missing entry但是(当然)结果值缺少条目

Why did I say "of course"?为什么我说“当然”? Because Swift dictionaries cannot have duplicated keys.因为 Swift 字典不能有重复的键。

Response(
    myDogs: [
        "goodBoy": Dog(color: "#000000"),
        "veryGoodBoy": Dog(color: "#FFFFFF")
    ]
)

4. Considerations 4.注意事项

So as far as I can see, the answer to your question is: NO, we cannot detect a duplicate key in the original JSON with JSONDecoder.因此,据我所知,您的问题的答案是:不,我们无法使用 JSONDecoder 检测到原始 JSON 中的重复键。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM