I am struggling to achieve the following and need your kind help in dealing with dictionaries in swift:
- How to get "Nobody" "Image" value? it should be "Nobody.png"
- How to the count of BestMoments members? (it should be 3 for first movie and 4 for second movie"
- 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:
movies.first { $0.name == "Nobody" }?.image
movies.first { $0.name == "Nobody" }?.bestMoments.count
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
.