1

I have a struct like:

struct Demo: Codable {
    var foo: String
    var bar: String
    ...
}

And I have an array of demo:

let array = [Demo(foo: "a", bar: "b"), Demo(foo: "c", bar: "d")]

And I want to convert this array to a Dictionary [[String: Any]] with something like this:

let dictionary:[[String : Any]] = array.toDictionaryFromArrayOfCodable()

How can I get it?

Edit: My expected output is something like, and I want to use JSONEncoder:

[["foo": "a", "bar": "b"], ["foo": "c", "bar": "d"]]
9
  • 2
    stackoverflow.com/questions/47922485/… ? Commented Aug 3, 2018 at 8:52
  • try this -> let dict = try JSONDecoder().decode([String: Any].self, from: JSONEncoder().encode(array)) Commented Aug 3, 2018 at 9:02
  • Edited with de expected output. Commented Aug 3, 2018 at 9:11
  • @vivekDas using decode([String: Any] I have an error: "Type 'Any does not conform to protocol 'Decodable'. Changing it to decode([String: String], it compiles but I have an error: typeMismatch(Swift.Dictionary<Swift.String, Any>, Swift.DecodingError.Context(codingPath: [], debugDescription: "Expected to decode Dictionary<String, Any> but found an array instead.", underlyingError: nil)) Commented Aug 3, 2018 at 9:24
  • Follow the link @Larme has provided. Commented Aug 3, 2018 at 9:28

1 Answer 1

2

I found a solution using two extensions: - First to get a dictionary from an object - Second, to create an array of dictionaries with each elements of an array, using first extension:

Usage:

let dictionary = [Demo].asDictionaryFromArray()
print(dictionary)

output as expected: [["bar": b, "foo": a], ["bar": d, "foo": c]]

extension Encodable {

    var dictionaryFromObject: [String: Any]? {
        guard let data = try? JSONEncoder().encode(self) else { return nil }
        return (try? JSONSerialization.jsonObject(with: data, options: .allowFragments)).flatMap { $0 as? [String: Any] }
    }

}

extension Array where Element: Encodable {

    func asDictionaryFromArray() -> [[String: Any]] {
        var dict = [[String: Any]]()

        _ = self.map {
            if let objectDict = $0.dictionaryFromObject {
                dict.append(objectDict)
            }
        }

        return dict
    }

}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.