skip to Main Content

What is the most efficient way to get the count of the unique values on a table?

For example:

fruitType
---------
banana
banana
apple
apple 
apple

bananas : 2
apples : 3

By using fruitsCollection.distinct(by: ["fruitType"]) i can get the distinct values but not the count.

Any help would be appreciated.

2

Answers


  1. you could try something simple like this (assuming fruits are Strings, adjust accordingly to your object types):

    let fruits = fruitsCollection.distinct(by: ["fruitType"])
    var results = [String:Int]()
    Set(fruits).forEach{ fruit in results[fruit] = (fruits.filter{$0 == fruit}).count }
    print("---> results: (results)")
    

    or

    let results: [String:Int] = Set(fruits).reduce(into: [:]) { dict, next in
                dict[next] = (fruits.filter{$0 == next}).count }
    
    print("---> results: (results)")
    

    The Set(fruits) gives you the unique set of fruit names. The filter{...} gives you the count of each. The forEach or the reduce turns the results into a dictionary of key values.

    Login or Signup to reply.
  2. @workingdog answer works very well but here’s a more Realmy option. Something to keep in mind is that Realm Results objects are lazily loaded – meaning working with very large datasets has a low memory impact.

    However, as soon high level Swift functions are used, that lazy-ness is lost and every object gobbles up memory.

    For example, loading 50,000 Realm objects into a Results object doesn’t have any significant memory impact – however, loading 50,000 objects into an Array could overwhelm the device as the objects loose their lazy-loading nature.

    With this solution, we rely on Realm to present unique values and store them in Results (lazy!) then iterating over those we filter for matching objects (lazy) and return their count.

    I created a FruitClass to hold the fruit types

    class FruitClass: Object {
        @Persisted var fruitType = ""
    }
    

    and then to code

    This is a very memory friendly solution
    
    //get the unique types of fruit. results are lazy!
    let results = realm.objects(FruitClass.self).distinct(by: ["fruitType"])
    
    //iterate over the results to get each fruit type, and then filter for those to get the count of each
    for fruit in results {
        let type = fruit.fruitType
        let count = realm.objects(FruitClass.self).filter("fruitType == %@", type).count
        print("(type) has a count of (count)")
    }
    

    and the results

    apple has a count of 3
    banana has a count of 2
    orange has a count of 1
    pear has a count of 1
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search