How to create array of unique object list in Swift

后端 未结 11 2028
猫巷女王i
猫巷女王i 2020-11-27 05:20

How can we create unique object list in Swift language like NSSet & NSMutableSet in Objective-C.

相关标签:
11条回答
  • 2020-11-27 05:36

    Always in such a case the critical factor is how to compare objects and what types of objects go into the Set. Using a Swift Dictionary, where the Set objects are the dictionary keys, could be a problem based on the restrictions on the key type (String, Int, Double, Bool, valueless Enumerations or hashable).

    If you can define a hash function on your object type then you can use a Dictionary. If the objects are orderable, then you could define a Tree. If the objects are only comparable with == then you'll need to iterate over the set elements to detect a preexisting object.

    // When T is only Equatable
    class Set<T: Equatable> {
      var items = Array<T>()
    
      func hasItem (that: T) {
       // No builtin Array method of hasItem... 
       //   because comparison is undefined in builtin Array   
       for this: T in items {
         if (this == that) {
           return true
         }
       }
       return false
      }
    
      func insert (that: T) {
        if (!hasItem (that))
          items.append (that)
      }
    }
    

    The above is an example of building a Swift Set; the example used objects that are only Equatable - which, while a common case, doesn't necessarily lead to an efficient Set implementations (O(N) search complexity - the above is an example).

    0 讨论(0)
  • 2020-11-27 05:41

    I've built an extensive Set type similar to the built-in Array and Dictionary - here are blog posts one and two and a GitHub repository:

    • Creating a Set Type in Swift
    • Set Type Follow-up
    • SwiftSets on GitHub
    0 讨论(0)
  • 2020-11-27 05:44

    Swift has no concept of sets. Using NSMutableSet in Swift might be slower than using a Dictionary that holds dummy values. You could do this :

    var mySet: Dictionary<String, Boolean> = [:]
    mySet["something"]= 1
    

    Then just iterate over the keys.

    0 讨论(0)
  • 2020-11-27 05:48

    You can use any Objective-C class in Swift:

    var set = NSMutableSet()
    set.addObject(foo)
    
    0 讨论(0)
  • 2020-11-27 05:54

    As of Swift 1.2 (Xcode 6.3 beta), Swift has a native set type. From the release notes:

    A new Set data structure is included which provides a generic collection of unique elements, with full value semantics. It bridges with NSSet, providing functionality analogous to Array and Dictionary.

    Here are some simple usage examples:

    // Create set from array literal:
    var set = Set([1, 2, 3, 2, 1])
    
    // Add single elements:
    set.insert(4)
    set.insert(3)
    
    // Add multiple elements:
    set.unionInPlace([ 4, 5, 6 ])
    // Swift 3: set.formUnion([ 4, 5, 6 ])
    
    // Remove single element:
    set.remove(2)
    
    // Remove multiple elements:
    set.subtractInPlace([ 6, 7 ])
    // Swift 3: set.subtract([ 6, 7 ])
    
    print(set) // [5, 3, 1, 4]
    
    // Test membership:
    if set.contains(5) {
        print("yes")
    }
    

    but there are far more methods available.

    Update: Sets are now also documented in the "Collection Types" chapter of the Swift documentation.

    0 讨论(0)
  • 2020-11-27 05:55

    You actually can create a Set object pretty easy (in contradiction to GoZoner, there is a built in contains method):

    class Set<T : Equatable> {
        var items : T[] = []
    
        func add(item : T) {
            if !contains(items, {$0 == item}) {
                items += item
            }
        }
    }
    

    and you maybe even want to declare a custom operator:

    @assignment @infix func += <T : Equatable> (inout set : Set<T>, items : T[]) -> Set<T> {
        for item in items {
            set.add(item)
        }
        return set
    }
    
    0 讨论(0)
提交回复
热议问题