How to create array of unique object list in Swift

2020-01-24 12:34发布

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

标签: swift nsset
11条回答
家丑人穷心不美
2楼-- · 2020-01-24 12:46

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).

查看更多
神经病院院长
3楼-- · 2020-01-24 12:47

You can use any Objective-C class in Swift:

var set = NSMutableSet()
set.addObject(foo)
查看更多
做个烂人
4楼-- · 2020-01-24 12:55

So I think creating a Set with an array is a terrible idea - O(n) is the time complexity of that set.

I have put together a nice Set that uses a dictionary: https://github.com/evilpenguin/Swift-Stuff/blob/master/Set.swift

查看更多
我命由我不由天
5楼-- · 2020-01-24 12:57

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.

查看更多
Root(大扎)
6楼-- · 2020-01-24 12:59

I wrote a function to solve this problem.

public func removeDuplicates<C: ExtensibleCollectionType where C.Generator.Element : Equatable>(aCollection: C) -> C {
    var container = C()

    for element in aCollection {
        if !contains(container, element) {
            container.append(element)
        }
    }

    return container
}

To use it, just pass an array which contains duplicate elements to this function. And then it will return a uniqueness-guaranteed array.

You also can pass a Dictionary, String or anything conforms to ExtensibleCollectionType protocol if you like.

查看更多
Deceive 欺骗
7楼-- · 2020-01-24 13:02

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:

查看更多
登录 后发表回答