Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
解析Swift 4中包含字符串和int的JSON数组_Json_Swift - Fatal编程技术网

解析Swift 4中包含字符串和int的JSON数组

解析Swift 4中包含字符串和int的JSON数组,json,swift,Json,Swift,我有一个简单的数组 Array[4][ "A", 1, "A1", 13 ] 但是,当JSON数组同时包含int和string时,如何解析它呢?如果还没有,我可以将里面的所有值转换成字符串,但是我找不到任何函数来实现这一点 谢谢 使用可编码的复杂方式 使用unkeyedContainer对数组进行解码 使用循环,同时使用条件!在一个do-catch块中对Int进行搜索和解码。如果解码字符串失败 使用传统的json串行化的简便方法 将对象反序列化为[CustomStringCo

我有一个简单的数组

Array[4][
 "A",
  1,
 "A1",
  13
]
但是,当JSON数组同时包含int和string时,如何解析它呢?如果还没有,我可以将里面的所有值转换成字符串,但是我找不到任何函数来实现这一点

谢谢

  • 使用
    可编码的复杂方式

    • 使用
      unkeyedContainer对数组进行解码
    • 使用
      循环,同时使用条件
      !在一个
      do-catch
      块中对
      Int
      进行搜索和解码。如果解码
      字符串失败
  • 使用传统的
    json串行化的简便方法

    • 将对象反序列化为
      [CustomStringConvertible]
      ,并使用
      “\($0)”将数组映射到
      [String]
  • 编辑:

    let jsonData = """
    ["A", 1, "A1", 13, 15, 2, "B"]
    """.data(using: .utf8)!
    
    do {
        let decodedArray = try JSONDecoder().decode([StringOrIntType].self, from:jsonData)
        // Here, you have your Array
        print(decodedArray) // [.string("A"), .int(1), .string("A1"), .int(13), .int(15), .int(2), .string("B")]
    
        // If you want to get elements from this Array, you might do something like below
        decodedArray.forEach({ (value) in
            if case .string(let integer) = value {
                print(integer) // "A", "A1", "B"
            }
            if case .int(let int) = value {
                print(int) // 1, 13, 15, 2
            }
        })
    } catch {
        print(error)
    }
    
    这是一个示例,如果项目是成对的且类型顺序相同,则如何使用
    Decodable
    解码数组:

    let jsonArray = """
    ["A", 1, "A1", 13]
    """
    
    struct Item : Decodable {
        var array = [String]()
    
        init(from decoder: Decoder) throws {
            var arrayContainer = try decoder.unkeyedContainer()
            while !arrayContainer.isAtEnd {
                let string = try arrayContainer.decode(String.self)
                let int = try arrayContainer.decode(Int.self)
                array.append(String(int))
                array.append(string)
            }
        }
    }
    
    let data = Data(jsonArray.utf8)
    do {
        let result = try JSONDecoder().decode(Item.self, from: data)
        print(result.array)
    } catch { print(error) }
    
  • 使用
    可编码的复杂方式

    • 使用
      unkeyedContainer对数组进行解码
    • 使用
      循环,同时使用条件
      !在一个
      do-catch
      块中对
      Int
      进行搜索和解码。如果解码
      字符串失败
  • 使用传统的
    json串行化的简便方法

    • 将对象反序列化为
      [CustomStringConvertible]
      ,并使用
      “\($0)”将数组映射到
      [String]
  • 编辑:

    let jsonData = """
    ["A", 1, "A1", 13, 15, 2, "B"]
    """.data(using: .utf8)!
    
    do {
        let decodedArray = try JSONDecoder().decode([StringOrIntType].self, from:jsonData)
        // Here, you have your Array
        print(decodedArray) // [.string("A"), .int(1), .string("A1"), .int(13), .int(15), .int(2), .string("B")]
    
        // If you want to get elements from this Array, you might do something like below
        decodedArray.forEach({ (value) in
            if case .string(let integer) = value {
                print(integer) // "A", "A1", "B"
            }
            if case .int(let int) = value {
                print(int) // 1, 13, 15, 2
            }
        })
    } catch {
        print(error)
    }
    
    这是一个示例,如果项目是成对的且类型顺序相同,则如何使用
    Decodable
    解码数组:

    let jsonArray = """
    ["A", 1, "A1", 13]
    """
    
    struct Item : Decodable {
        var array = [String]()
    
        init(from decoder: Decoder) throws {
            var arrayContainer = try decoder.unkeyedContainer()
            while !arrayContainer.isAtEnd {
                let string = try arrayContainer.decode(String.self)
                let int = try arrayContainer.decode(Int.self)
                array.append(String(int))
                array.append(string)
            }
        }
    }
    
    let data = Data(jsonArray.utf8)
    do {
        let result = try JSONDecoder().decode(Item.self, from: data)
        print(result.array)
    } catch { print(error) }
    

    将JSON示例
    [1,“1”]
    粘贴到中可以实现以下
    Codable
    实现:

    typealias IntOrStrings = [IntOrString]
    
    enum IntOrString: Codable {
        case integer(Int)
        case string(String)
    
        init(from decoder: Decoder) throws {
            let container = try decoder.singleValueContainer()
            if let x = try? container.decode(Int.self) {
                self = .integer(x)
                return
            }
            if let x = try? container.decode(String.self) {
                self = .string(x)
                return
            }
            throw DecodingError.typeMismatch(IntOrString.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Wrong type for IntOrString"))
        }
    
        func encode(to encoder: Encoder) throws {
            var container = encoder.singleValueContainer()
            switch self {
            case .integer(let x):
                try container.encode(x)
            case .string(let x):
                try container.encode(x)
            }
        }
    }
    
    这允许您执行以下操作:

    let items = try IntStrings("[1, \"1\"]")
    // Now you have:
    // items == [.integer(1), .string("1")]
    // so you can map or iterate over this
    

    这是从JSON中表示整型或字符串数组的最安全的方式。

    将JSON示例
    [1,“1”]
    粘贴到中可以实现以下
    可编码的实现:

    typealias IntOrStrings = [IntOrString]
    
    enum IntOrString: Codable {
        case integer(Int)
        case string(String)
    
        init(from decoder: Decoder) throws {
            let container = try decoder.singleValueContainer()
            if let x = try? container.decode(Int.self) {
                self = .integer(x)
                return
            }
            if let x = try? container.decode(String.self) {
                self = .string(x)
                return
            }
            throw DecodingError.typeMismatch(IntOrString.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Wrong type for IntOrString"))
        }
    
        func encode(to encoder: Encoder) throws {
            var container = encoder.singleValueContainer()
            switch self {
            case .integer(let x):
                try container.encode(x)
            case .string(let x):
                try container.encode(x)
            }
        }
    }
    
    这允许您执行以下操作:

    let items = try IntStrings("[1, \"1\"]")
    // Now you have:
    // items == [.integer(1), .string("1")]
    // so you can map or iterate over this
    

    这是从JSON中表示整型或字符串数组的最安全的方式。

    您将得到
    数组
    元素,如
    字符串
    整型
    ,类似于
    枚举
    类型的数组。因此,您可以在
    枚举的帮助下解析底层
    类型

    将基础类型结构化为:

    enum StringOrIntType: Codable {
        case string(String)
        case int(Int)
    
        init(from decoder: Decoder) throws {
            let container = try decoder.singleValueContainer()
            do {
                self = try .string(container.decode(String.self))
            } catch DecodingError.typeMismatch {
                do {
                    self = try .int(container.decode(Int.self))
                } catch DecodingError.typeMismatch {
                    throw DecodingError.typeMismatch(StringOrIntType.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Encoded payload not of an expected type"))
                }
            }
        }
    
        func encode(to encoder: Encoder) throws {
            var container = encoder.singleValueContainer()
            switch self {
            case .int(let int):
                try container.encode(int)
            case .string(let string):
                try container.encode(string)
            }
        }
    }
    
    解码过程:

    let jsonData = """
    ["A", 1, "A1", 13, 15, 2, "B"]
    """.data(using: .utf8)!
    
    do {
        let decodedArray = try JSONDecoder().decode([StringOrIntType].self, from:jsonData)
        // Here, you have your Array
        print(decodedArray) // [.string("A"), .int(1), .string("A1"), .int(13), .int(15), .int(2), .string("B")]
    
        // If you want to get elements from this Array, you might do something like below
        decodedArray.forEach({ (value) in
            if case .string(let integer) = value {
                print(integer) // "A", "A1", "B"
            }
            if case .int(let int) = value {
                print(int) // 1, 13, 15, 2
            }
        })
    } catch {
        print(error)
    }
    
    从对已接受答案的评论来看:您不必再担心物品的顺序。


    您将获得元素的
    Array
    作为
    String
    Int
    ,这类似于
    enum
    类型的数组。因此,您可以在
    枚举的帮助下解析底层
    类型

    将基础类型结构化为:

    enum StringOrIntType: Codable {
        case string(String)
        case int(Int)
    
        init(from decoder: Decoder) throws {
            let container = try decoder.singleValueContainer()
            do {
                self = try .string(container.decode(String.self))
            } catch DecodingError.typeMismatch {
                do {
                    self = try .int(container.decode(Int.self))
                } catch DecodingError.typeMismatch {
                    throw DecodingError.typeMismatch(StringOrIntType.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Encoded payload not of an expected type"))
                }
            }
        }
    
        func encode(to encoder: Encoder) throws {
            var container = encoder.singleValueContainer()
            switch self {
            case .int(let int):
                try container.encode(int)
            case .string(let string):
                try container.encode(string)
            }
        }
    }
    
    解码过程:

    let jsonData = """
    ["A", 1, "A1", 13, 15, 2, "B"]
    """.data(using: .utf8)!
    
    do {
        let decodedArray = try JSONDecoder().decode([StringOrIntType].self, from:jsonData)
        // Here, you have your Array
        print(decodedArray) // [.string("A"), .int(1), .string("A1"), .int(13), .int(15), .int(2), .string("B")]
    
        // If you want to get elements from this Array, you might do something like below
        decodedArray.forEach({ (value) in
            if case .string(let integer) = value {
                print(integer) // "A", "A1", "B"
            }
            if case .int(let int) = value {
                print(int) // 1, 13, 15, 2
            }
        })
    } catch {
        print(error)
    }
    
    从对已接受答案的评论来看:您不必再担心物品的顺序。


    哦,我想为我的整个应用程序保持可编码,但是这个JSON非常复杂(这个数组只是整个应用程序的一部分)。我想我会坚持使用JSONSerialization来完成这一步。谢谢,瓦迪安!如果项目是成对的,并且顺序
    String
    Int
    String
    Int
    是有保证的,那么
    Codable
    就不那么复杂,可能更有效。在
    的每次迭代中,当
    循环解码对时,顺序总是相同的。你能举个简单的例子吗?谢谢很好的解决方案!非常感谢瓦迪安。您帮了我很多。@vadian,实际上,通过使用
    关联枚举
    类型,可以在这里放弃排序。
    Codable
    不再复杂,而且
    init(from:)
    更干净。检查我的答案。哦,我想为我的整个应用程序保持可编码,但是这个JSON非常复杂(这个数组只是整个应用程序的一部分)。我想我会坚持使用JSONSerialization来完成这一步。谢谢,瓦迪安!如果项目是成对的,并且顺序
    String
    Int
    String
    Int
    是有保证的,那么
    Codable
    就不那么复杂,可能更有效。在
    的每次迭代中,当
    循环解码对时,顺序总是相同的。你能举个简单的例子吗?谢谢很好的解决方案!非常感谢瓦迪安。您帮了我很多。@vadian,实际上,通过使用
    关联枚举
    类型,可以在这里放弃排序。
    Codable
    不再复杂,而且
    init(from:)
    更干净。检查我的答案。另一方面,对错误处理要更加明确。您可以省略
    init(from:)
    中的条件绑定。请参阅我的答案。另一方面,请更明确地说明错误处理。您可以省略
    init(from:)
    中的条件绑定。看看我的答案。哇,这是一个很好的解决方案!谢谢你,内姆。这太简单了,我打算改用你的。哇,这是一个很好的解决方案!谢谢你,内姆。这太简单了,我打算改用你的。