GO FURTHER, FASTER: Try the Swift Career Accelerator today! >>

How to transform a grouped NSDictionary

Forums > Swift

I have an app that allows you to rate media 0-5 stars as integers using Core Data. I have the aggregate fetch request using propertiesToGroupBy to return a count of each media type and rating. The print() result of the request is

[
    ["rating": 0, "count": 17, "type": movie], 
    ["count": 10, "rating": 0, "type": show], 
    ["count": 8, "type": movie, "rating": 1], 
    ["rating": 2, "count": 36, "type": movie], 
    ["rating": 2, "count": 15, "type": show], 
    ["type": movie, "count": 161, "rating": 3], 
    ["rating": 3, "type": show, "count": 26], 
    ["rating": 4, "count": 217, "type": movie], 
    ["count": 48, "rating": 4, "type": show], 
    ["type": movie, "rating": 5, "count": 114], 
    ["count": 63, "rating": 5, "type": show],
    ["count": 8, "rating": 4, "type": web]
]

returned as an NSDictionary/dictionaryResultType. I would like to transform this result into separate integer arrays for each type, with the count for each rating 5-0, even if there is no result for the combination of type and rating. Something like:

ratings = [5, 4, 3, 2, 1, 0]

and then

movie = [114, 217, 161, 36, 8, 17]
show = [63, 48, 26, 15, 0, 10]
web = [0, 8, 0, 0, 0, 0]

Is there an efficient way to do this, like with mapping or grouped dictionaries?

3      

hi Brian,

what you show is an array of dictionaries; and if you have defined the values movie, show, and web to be, say integers, you have something of type [[String : Int]]. so this code works:

let movie = 1 // my assumptions
let show = 2
let web = 3

let myArray = [
    ["rating": 0, "count": 17, "type": movie],
  //
  // and other data as shown above ...
  //
    ["count": 8, "rating": 4, "type": web]
]

// finds the one entry, if any, for the given type and rating and returns 
// the count, else returns 0
func count(type: Int, rating: Int) -> Int {
    let dictionaryEntry = myArray.first(where: { $0["type"] ==  type && $0["rating"] == rating })
    return dictionaryEntry?["count"] ?? 0
}

let ratings = [5,4,3,2,1,0]
print(ratings.map({ count(type: movie, rating: $0) }))
print(ratings.map({ count(type: show, rating: $0) }))
print(ratings.map({ count(type: web, rating: $0) }))

hope that helps,

DMG

3      

Hacking with Swift is sponsored by RevenueCat.

SPONSORED Take the pain out of configuring and testing your paywalls. RevenueCat's Paywalls allow you to remotely configure and A/B test your entire paywall UI without any code changes or app updates.

Learn more here

Sponsor Hacking with Swift and reach the world's largest Swift community!

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.