Home > Blockchain >  How to retrieve deeply nested data form SWIFT dictionary?
How to retrieve deeply nested data form SWIFT dictionary?

Time:09-16

I am struggling to achieve the following and need your kind help in dealing with dictionaries in swift:

  1. How to get "Nobody" "Image" value? it should be "Nobody.png"
  2. How to the count of BestMoments members? (it should be 3 for first movie and 4 for second movie"
  3. how to get values inside Bestmoments for "Nobody" (like :"Survive", 120, 8)?
 var MV = [
        ["Nobody": [
            ["YEAR" : "2021"] ,
            ["IMAGE" : "Nobody.png"] ,
            ["GENRE" : "Action/Thriller"] ,
            ["DURATIONhours" : 1] ,
            ["DURATIONmintues" : 36] ,
            ["DURATIONseconds" : 17] ,
            ["BestMoments" : [["Win", 25, 5], ["Survive", 120, 8], ["Lose", 240, 15]]]
        ]],
        ["Godzilla vs. Kong": [
            ["YEAR" : "2021"] ,
            ["IMAGE" : "Nobody.png"] ,
            ["GENRE" : "Action/Sci-fi"] ,
            ["DURATIONhours" : 1] ,
            ["DURATIONmintues" : 22] ,
            ["DURATIONseconds" : 45] ,
            ["BestMoments" : [["Win", 34, 6], ["Survive", 120, 8], ["Twist", 233, 3], ["Lose", 340, 12]]]
        ]],
    ]

I tried the following to access the data (with outcome):

print(MV[0])
// prints all data for the first movie

print(MV["Nobody"])
// No exact matches in call to subscript

print([MV[0].keys])
// prints the name of the first movie which is the key

for (movie, data) in MV2 {
        print(data)
        }

//Tuple pattern cannot match values of non-tuple type [String : [[String : Any]]]

CodePudding user response:

The data in question has a very complex data structure and is difficult to manage. I think it would be better to have a simpler structure.

However, you can access the data you want in the following way. Try to print the result.

/// 1. How to get "Nobody" "Image" value? it should be "Nobody.png"
let imageOfNobady = MV[0]["Nobody"]![1]["IMAGE"]

/// 2. How to the count of BestMoments members? (it should be 3 for first movie and 4 for second movie"
let bestmomentsForNobady = MV[0]["Nobody"]![6]["BestMoments"] as! [Any]
let countOfBestmomentsForNobady = bestmomentsForNobady.count

/// 3. how to get values inside Bestmoments for "Nobody" (like :"Survive", 120, 8)?
let survieInfo = bestmomentsForNobady[1]

CodePudding user response:

Represent the data better:

struct BestMoment {
    enum MomentType: String {
        case win = "Win"
        case survive = "Survive"
        case lose = "Lose"
        case twist = "Twist"
    }

    let type: MomentType
    let start: Int
    let duration: Int
}

struct Duration {
    let hours: Int
    let minutes: Int
    let seconds: Int
}

struct Movie {
    let name: String
    let year: Int
    let image: String
    let genre: String
    let duration: Duration
    let bestMoments: [BestMoment]
}

let movies = [
    Movie(
        name: "Nobody",
        year: 2021,
        image: "Nobody.png",
        genre: "Action/Thriller",
        duration: Duration(hours: 1, minutes: 36, seconds: 16),
        bestMoments: [
            BestMoment(type: .win, start: 25, duration: 5),
            BestMoment(type: .survive, start: 120, duration: 8),
            BestMoment(type: .lose, start: 240, duration: 15)
        ]
    ),
    Movie(
        name: "Godzilla vs. Kong",
        year: 2021,
        image: "Nobody.png",
        genre: "Action/Sci-fi",
        duration: Duration(hours: 1, minutes: 22, seconds: 45),
        bestMoments: [
            BestMoment(type: .win, start: 34, duration: 6),
            BestMoment(type: .survive, start: 120, duration: 8),
            BestMoment(type: .twist, start: 233, duration: 3),
            BestMoment(type: .lose, start: 340, duration: 12)
        ]
    )
]

Then your operations are simple:

  1. movies.first { $0.name == "Nobody" }?.image
  2. movies.first { $0.name == "Nobody" }?.bestMoments.count
  3. movies.first { $0.name == "Nobody" }?.bestMoments

You could probably even wrap your movie library into an additional object that will simplify the search of movies.

Duration should be probably represented only in seconds and converted to hours/minutes/seconds only when needed. Genre could be probably an enum.

  • Related