我有一个名为Info的结构,该结构根据接收到的数据进行解码。但是有时,数据中的值之一可以是double或double数组。我该如何设置我的结构?
这是我的结构:
struct Info: Decodable {
let author: String
let title: String
let tags: [Tags]
let price: [Double]
enum Tags: String, Decodable {
case nonfiction
case biography
case fiction
}
}
根据网址,我要么获得双倍价格
{
"author" : "Mark A",
"title" : "The Great Deman",
"tags" : [
"nonfiction",
"biography"
],
"price" : "242"
}
或者我将其作为双打数组
{
"author" : "Mark A",
"title" : "The Great Deman",
"tags" : [
"nonfiction",
"biography"
],
"price" : [
"242",
"299",
"335"
]
}
我想设置结构,以便如果我收到一个double而不是一个double数组,则应该将price解码为1个double的数组。
我们将不胜感激。
谢谢
答案 0 :(得分:5)
您的JSON实际上是一个字符串或一个字符串数组。因此,您需要创建一个自定义解码器进行解码,然后将其转换为Double:
extension Info: Codable {
public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
author = try container.decode(String.self, forKey: .author)
title = try container.decode(String.self, forKey: .title)
tags = try container.decode([Tags].self, forKey: .tags)
do {
price = try [Double(container.decode(String.self, forKey: .price)) ?? .zero]
} catch {
price = try container.decode([String].self, forKey: .price).compactMap(Double.init)
}
}
}
let infoData = Data("""
{
"author" : "Mark A",
"title" : "The Great Deman",
"tags" : [
"nonfiction",
"biography"
],
"price" : "242"
}
""".utf8)
do {
let info = try JSONDecoder().decode(Info.self, from: infoData)
print("price",info.price) // "price [242.0]\n"
} catch {
print(error)
}
游乐场测试
let infoData2 = Data("""
{
"author" : "Mark A",
"title" : "The Great Deman",
"tags" : [
"nonfiction",
"biography"
],
"price" : [
"242",
"299",
"335"
]
}
""".utf8)
do {
let info = try JSONDecoder().decode(Info.self, from: infoData2)
print("price",info.price) // "price [242.0, 299.0, 335.0]\n"
} catch {
print(error)
}
<!DOCTYPE html>
<head>
<title>Feedback Form</title>
<style>
h1 { color: red; padding: 10px; text-decoration: underline; }
.defaultTextBox {
padding: 0;
height: 20px;
position: relative;
left: 0;
outline: none;
border: 1px solid #cdcdcd;
border-color: rgba(0,0,0,.15);
background-color: white;
font-size: 16px;
.defaultTextArea {
padding: 0;
height: 100px;
position: relative;
left: 0;
outline: none;
border: 1px solid #cdcdcd;
border-color: rgba(0,0,0,.15);
background-color: white;
font-size: 16px;
.button {
background-color: #4CAF50; /* Green */
border: none;
color: white;
padding: 15px 32px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
}
}
</style>
</head>
<body>
<script>
function formsubmission(){
alert("Thank you for submitting feedback");
if(ValidateEmail()){
if(textAreaValidation()){
if(phoneNumberValidation()){
return true;
}else{
return false;
}
}else{
return false;
}
}
}
function ValidateEmail()
{
if (/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/.test(registraionForm.emailTxt.value))
{
return (true)
}
alert("You have entered an invalid email address!")
return (false)
}
function textAreaValidation()
{
var comments = registraionForm.comments.value;
if(comments.length == 0)
{
return (false);
}
else
{
return (true);
}
}
function phoneNumberValidation()
{
var p1 = phone.search(/^\d{3}[-\s]{0,1}\d{3}[-\s]{0,1}\d{4}$/);
var p2 = phone.search(/^\d{3}[-\s]{0,1}\d{4}$/);
if(p1 == 0 || p2 == 0)
{
return true;
}
else
{
return false;
}
}
</script
<h1 >Please Provide The Daily Grind Your Feedback</h1>
<tr><td><form name="FeedbackForm" method="post" action="processcontact.php">
<Table>
<TD>
<Table border="0">
<TR>
<TD><label>First Name</label></TD>
<TD><input type="text" name="FirstNameTxt" required class="defaultTextBox" /></TD>
</TR>
<TR>
<TD><label>Last Name</label></TD>
<TD><input type="text" name="LastNameTxt" required class="defaultTextBox" /></TD>
</TR>
<TR>
<TD><label>Phone Number</label></TD>
<TD><input type="text" name="PhoneTxt" required class="defaultTextBox" /></TD>
</TR>
<TR>
<TD><label>Email</label></TD>
<TD><input type="text" name="emailTxt" required class="defaultTextBox" /></TD>
</TR>
<TR>
<TD><label>Subject</label></TD>
<TD><input type="text" name="SubjectTxt" required class="defaultTextBox" /></TD>
</TR>
<TR>
<td colspan="2">Please check here if you wish to receive a reply:
<input type="checkbox" name="reply" value= "yes" /></td>
</TD>
</TR>
<TR>
<TD>Comments</TD>
<TD>
<textarea name="comments" rows="4" cols="50" class="defaultTextArea" >Write your feedback here</textarea>
</TD>
</TR>
<TR>
<TD> </TD>
<TD><input type="submit" name="formSubmit" value="Submit" onclick="formSubmit();"/></TD>
</TR>
</Table>
</TD>
</TR>
</Table>
</form>
</body>
</html>